【问题标题】:I need to write query for numbers of occurance我需要编写查询出现次数
【发布时间】:2013-04-10 08:41:28
【问题描述】:
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 

只有具有相同file_id并具有3种状态的行:1,2,3 whis相同日期,一一发生需要计为一次发生

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

感谢和问候

【问题讨论】:

  • select count(count_occure) from (select count(status) as count_occure from my_table where status in (1,2,3) group by file_id, date_occure 有 count(atatus_id)=3)a) -它不正确
  • @user2265127 请用该评论更新您的问题! :)
  • 如果同一天内有更多的连续 (1-2-3) 事件怎么办?是否有效?

标签: sql sql-server-2008 tsql count


【解决方案1】:

我认为您的问题源于您想按天分组,但您的专栏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

【讨论】:

    猜你喜欢
    • 2013-01-01
    • 2011-03-14
    • 1970-01-01
    • 1970-01-01
    • 2017-11-23
    • 1970-01-01
    • 2019-10-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多