我有这张表,活动:
| 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?
a b a b a b ..
当然我会根据活动日期进行检查
答案 0 :(得分:0)
在SQL Server 2012+中,您可以将common table expression与lag()
一起使用,然后使用跟随您的逻辑的min()
表达式的case
,如下所示:
;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
答案 1 :(得分:0)
EDITED - 允许每个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
答案 2 :(得分: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
根据解释,必须为正确的顺序实施以下逻辑。
a
和第二行b
,最低活动为a
,最高活动为b
。lag
设置)应为0