file_id status date_occure
1 1 2013-04-10:3:26
1 2 2013-04-10:3:27
1 3 2013-04-10:3:28
只有行与文件_id相同且有3种状态:1,2,3个相同的日期,一个接一个地发生需要算作一次出现
-----------------------------------
1 4 2013-04-10:3:26
rows whis another statuses not be counted
----------------------------------
1 1 2013-04-10:3:26
1 3 2013-04-10:3:27
1 2 2013-04-10:3:28
also rows ordered by date but statuses no (1->2->3) not be counted
-----------------------------------
表格包含许多行,结果必须按file_id
分组。
谢谢和问候
答案 0 :(得分:2)
我认为您的问题源于您希望按天分组,但您的列Date_occure
也存储时间。我不是100%确定您需要的确切输出,但这应该为您提供所需的一切:
WITH CTE AS
( SELECT [File_ID],
[Status],
Date_Occure,
Occurrences = COUNT(CASE WHEN [Status] IN (1, 2, 3) THEN [Status] END) OVER(PARTITION BY [File_ID], CAST(Date_Occure AS DATE)),
RowNumber = ROW_NUMBER() OVER(PARTITION BY [File_ID], CAST(Date_Occure AS DATE) ORDER BY Date_Occure, [Status] DESC)
FROM T
)
SELECT [File_ID], [Status], Date_Occure, Occurrences
FROM CTE
WHERE RowNumber = 1;
关键是按CAST(Date_Occure AS DATE)
分区,而不仅仅是date_occure
。
简化版本为:
SELECT [File_ID],
Date_Occure = MIN(Date_Occure),
Occurrences = COUNT(CASE WHEN [Status] IN (1, 2, 3) THEN [Status] END)
FROM T
GROUP BY [File_ID], CAST(Date_Occure AS DATE);
编辑
我刚刚重新阅读了这个问题,并认为我现在理解了这些标准。
如果全部三个状态(1,2,3)必须按顺序出现,那么您可以使用它:
SELECT [File_ID],
Date_Occure = MIN(Date_Occure)
FROM T
WHERE NOT EXISTS
( SELECT 1
FROM T T2
WHERE T2.[File_ID] = t.[File_ID]
AND CAST(T2.Date_Occure AS DATE) = CAST(T.Date_Occure AS DATE)
AND T2.[Status] > T.[Status]
AND T2.Date_Occure < T.Date_Occure
)
GROUP BY [File_ID]
HAVING COUNT(DISTINCT CASE WHEN [Status] IN (1, 2, 3) THEN [Status] END) = 3;
NOT EXISTS
确保不存在具有无序状态的记录,HAVING
确保所有3状态(1,2,3)都存在。
如果您只想要所有状态在特定日期都是连续的文件,那么您可以使用类似的内容按状态顺序对记录进行排名,并按日期顺序对其进行排名,并排除存在错误的文件匹配:
WITH CTE AS
( SELECT [File_ID],
[Status],
Date_Occure,
DateOrder = ROW_NUMBER() OVER(PARTITION BY [File_ID], CAST(Date_Occure AS DATE) ORDER BY [Status], Date_Occure ASC),
StatusOrder = ROW_NUMBER() OVER(PARTITION BY [File_ID], CAST(Date_Occure AS DATE) ORDER BY Date_Occure, [Status] ASC),
Occurrences = COUNT(*) OVER(PARTITION BY [File_ID], CAST(Date_Occure AS DATE)),
RowNumber = ROW_NUMBER() OVER(PARTITION BY [File_ID], CAST(Date_Occure AS DATE) ORDER BY Date_Occure, [Status] DESC)
FROM T
)
SELECT [File_ID], [Status], Date_Occure, Occurrences
FROM CTE
WHERE RowNumber = 1
AND NOT EXISTS
( SELECT 1
FROM CTE T2
WHERE T2.[File_ID] = CTE.[File_ID]
AND CAST(T2.Date_Occure AS DATE) = CAST(CTE.Date_Occure AS DATE)
AND T2.DateOrder != T2.StatusOrder
);
<强> Examples on SQL Fiddle 强>