2017-08-25 35 views
0

我有這個表,活動時間:如何檢查每個唯一ID的列值(按日期)的順序?

| ID | Date of activity | activity | 
|----|---------------------|----------| 
| 1 | 2016-05-01T13:45:03 | a  | 
| 1 | 2016-05-02T13:45:03 | b  | 
| 1 | 2016-05-03T13:45:03 | a  | 
| 1 | 2016-05-04T13:45:03 | b  | 
| 2 | 2016-05-01T13:45:03 | b  | 
| 2 | 2016-05-02T13:45:03 | b  | 

與此表:

| id | Right order | 
|----|-------------| 
| 1 | yes   | 
| 2 | no   | 

我如何檢查每一個ID,如果活動的順序是sumiliar這個順序的例子嗎?

a b a b a b .. 
當然

我會根據活動日期

+0

我不清楚你問什麼? – ssn

+0

請澄清你的問題。這有點混亂。向我們展示一個輸出示例。 –

+0

從您發佈的數據來看,這是不可能的。根據定義,表格是一個無序集合,你沒有任何東西可以提供一致的順序。 –

回答

0

在SQL Server 2012+你可以使用common table expressionlag()檢查,然後case表達的min()後面,像這樣你的邏輯:

;with cte as (
    select * 
     , prev_activity = lag(activity) over (partition by id order by date_of_activity) 
    from t 
) 
select id 
    , right_order = min(case 
     when activity = 'a' and isnull(prev_activity,'b')<>'b' then 'no' 
     when activity = 'b' and isnull(prev_activity,'b')<>'a' then 'no' 
     else 'yes' 
    end) 
from cte 
group by id 

rextester演示:http://rextester.com/NQQF78056

回報:

+----+-------------+ 
| id | right_order | 
+----+-------------+ 
| 1 | yes   | 
| 2 | no   | 
+----+-------------+ 

之前的SQL Server 2012中您可以使用outer apply()獲得以前的活動,而不是lag()像這樣:

select id 
    , right_order = min(case 
     when activity = 'a' and isnull(prev_activity,'b')<>'b' then 'no' 
     when activity = 'b' and isnull(prev_activity,'b')<>'a' then 'no' 
     else 'yes' 
    end) 
from t 
    outer apply (
    select top 1 prev_activity = i.activity 
    from t as i 
    where i.id = t.id 
     and i.date_of_activity < t.date_of_activity 
    order by i.date_of_activity desc 
    ) x 
group by id 
0

編輯 - 允許每個ID模式的變量數

也許另一方法

實施例基於以下邏輯具有解釋

Declare @Pat varchar(max)='a b' 
Declare @Cnt int = 2 

Select ID 
     ,RightOrder = case when rtrim(replicate(@Pat+' ',Hits/@Cnt)) = (Select Stuff((Select ' ' +activity From t Where id=A.id order by date_of_activity For XML Path ('')),1,1,'')) then 'Yes' else 'No' end 
From (Select ID,hits=count(*) from t group by id) A 

返回

ID RightOrder 
1 Yes 
2 No 
0
select id, 
case when sum(flag)=0 and cnt_per_id%2=0 
    and max(case when rnum=1 then activity end) = 'a' 
    and max(case when rnum=2 then activity end) = 'b' 
    and min_activity = 'a' and max_activity = 'b' 
then 'yes' else 'no' end as RightOrder 
from (select t.* 
     ,row_number() over(partition by id order by activitydate) as rnum 
     ,count(*) over(partition by id) as cnt_per_id 
     ,min(activity) over(partition by id) as min_activity 
     ,max(activity) over(partition by id) as max_activity 
     ,case when lag(activity) over(partition by id order by activitydate)=activity then 1 else 0 end as flag 
     from tbl t 
    ) t 
group by id,cnt_per_id,max_activity,min_activity 

爲rightorder來實現。

  • 檢查每個ID的行數是偶數(除去此條件是否存在可以是奇數像a行,B,A的或A,B,A,B,A等)
  • 第一行包含a和第二行b,最小行爲爲a,最大行爲爲b
  • 總和標誌(使用lag集)應該是0
相關問題