我需要为出现次数编写查询

时间:2013-04-10 08:41:29

标签: sql sql-server-2008 tsql count

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分组。

谢谢和问候

1 个答案:

答案 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