【问题标题】:Group and Stuff multiple rows based on Count condition根据计数条件对多行进行分组和填充
【发布时间】:2016-04-11 15:21:59
【问题描述】:

我有一个脚本,每 10 分钟运行一次,并返回包含过去 24 小时事件的表格(由脚本运行时间标记)

ID      Name                TimeOfEvent                 EventCategory       TeamColor
1       Verlene Bucy        2015-01-30 09:10:00.000         1                   Blue
2       Geneva Rendon       2015-01-30 09:20:00.000         2                   Blue
3       Juliane Hartwig     2015-01-30 09:25:00.000         3                   Blue
4       Vina Dutton         2015-01-30 12:55:00.000         2                   Red
5       Cristin Lewis       2015-01-30 15:50:00.000         2                   Red
6       Reiko Cushman       2015-01-30 17:10:00.000         1                   Red
7       Mallie Temme        2015-01-30 18:35:00.000         3                   Blue
8       Keshia Seip         2015-01-30 19:55:00.000         2                   Blue
9       Rosalia Maher       2015-01-30 20:35:00.000         3                   Red
10      Keven Gabel         2015-01-30 21:25:00.000         3                   Red

现在我想根据这些条件选择两组名称:

1) 从过去 24 小时内有 4 条或更多记录的同一 EventCategory 中选择名称。

2) 从过去 1 小时内有 2 条或更多记录的相同 EventCategory 和相同 TeamColor 中选择名称。

所以我的结果是:

4+per24h: Geneva Rendon, Vina Dutton, Cristin Lewis, Keshia Seip        EventCategory = 2
4+per24h: Juliane Hartwig, Mallie Temme, Rosalia Maher, Keven Gabel     EventCategory = 3
2+per1h:  Rosalia Maher, Keven Gabel                                    EventCategory = 3, TeamColor = Red

对于第一个,我写了这个:

SELECT mt.EventCategory, MAX(mt.[name]), MAX(mt.TimeOfEvent), MAX(mt.TeamColor)
  FROM #mytable mt
GROUP BY mt.EventCategory
HAVING COUNT(mt.EventCategory) >= 4

因为我不关心实际时间,只要它在过去 24 小时内(而且总是如此),但我很难将名称塞入一行。

第二部分,我不知道该怎么做。因为结果需要具有相同的 EventCategory 和 TeamColor 并且还需要被一小时括号限制。

【问题讨论】:

    标签: tsql sql-server-2005 aggregate


    【解决方案1】:

    这是可能的,但是您将两个不同的问题混为一谈。在这里您可以找到它们与UNION 的组合:

    只需将其粘贴到一个空的查询窗口中并执行。适应您的需求:

    DECLARE @tbl TABLE(ID INT,Name VARCHAR(100),TimeOfEvent DATETIME,EventCategory INT,TeamColor VARCHAR(10));
    INSERT INTO @tbl VALUES
     (1,'Verlene Bucy','2015-01-30T09:10:00.000',1,'Blue')
    ,(2,'Geneva Rendon','2015-01-30T09:20:00.000',2,'Blue')
    ,(3,'Juliane Hartwig','2015-01-30T09:25:00.000',3,'Blue')
    ,(4,'Vina Dutton','2015-01-30T12:55:00.000',2,'Red')
    ,(5,'Cristin Lewis','2015-01-30T15:50:00.000',2,'Red')
    ,(6,'Reiko Cushman','2015-01-30T17:10:00.000',1,'Red')
    ,(7,'Mallie Temme','2015-01-30T18:35:00.000',3,'Blue')
    ,(8,'Keshia Seip','2015-01-30T19:55:00.000',2,'Blue')
    ,(9,'Rosalia Maher','2015-01-30T20:35:00.000',3,'Red')
    ,(10,'Keven Gabel','2015-01-30T21:25:00.000',3,'Red');
    
    WITH Extended AS
    (
        SELECT *
              ,DATEDIFF(MINUTE,'2015-01-30T21:26:00.000',TimeOfEvent) AS MinuteDiff --use GETDATE() here...
              ,COUNT(*) OVER(PARTITION BY EventCategory) AS CountCategory
        FROM @tbl AS tbl
    )
    ,Filtered24Hours AS
    (
        SELECT *
        FROM Extended
        WHERE CountCategory >=4
    )
    ,Filtered60Mins AS
    (
        SELECT *
        FROM Extended
        WHERE MinuteDiff >=-60 
          AND CountCategory >=2
    )
    SELECT DISTINCT (SELECT COUNT(*) FROM Filtered24Hours AS x WHERE x.EventCategory=outerSource.EventCategory) AS CountNames
                   ,'per24h' AS TimeIntervall
                   ,STUFF((
                            SELECT ' ,' + innerSource.Name 
                            FROM Filtered24Hours AS innerSource
                            WHERE innerSource.EventCategory=outerSource.EventCategory
                            ORDER BY innerSource.TimeOfEvent
                            FOR XML PATH('') 
                           ),1,2,'') AS Names 
                  ,EventCategory 
                  ,NULL
    FROM Filtered24Hours AS outerSource
    UNION 
    SELECT DISTINCT (SELECT COUNT(*) FROM Filtered60Mins AS x WHERE x.EventCategory=outerSource.EventCategory) 
                   ,'per1h'
                   ,STUFF((
                            SELECT ' ,' + innerSource.Name 
                            FROM Filtered60Mins AS innerSource
                            WHERE innerSource.EventCategory=outerSource.EventCategory
                            ORDER BY innerSource.TimeOfEvent
                            FOR XML PATH('') 
                           ),1,2,'') 
                  ,EventCategory 
                  ,TeamColor
    FROM Filtered60Mins AS outerSource
    

    结果

    Count Interv    Names                                                     Category  Team
    4     per24h    Geneva Rendon ,Vina Dutton ,Cristin Lewis ,Keshia Seip    2         NULL
    4     per24h    Juliane Hartwig ,Mallie Temme ,Rosalia Maher ,Keven Gabel 3         NULL
    2     per1h     Rosalia Maher ,Keven Gabel                                3         Red
    

    【讨论】:

    • 我只有一分钟的时间来测试它,但我的 sql-server 2005 无法处理“WITH Extended AS”。稍后我会好好看看。
    • @Zikato,我无法在 SQLServer 2005 上对此进行测试,但 WITH myCTE should work... 请注意 WITH myCTE 必须 与行分开前加分号。因此,在任何地方都使用;WITH...(见 WITH 之前的分号?)是很常见的......
    • 谢谢,确实是这个问题。该解决方案有效,现在我只需要研究一下即可了解原因。在此之前我对 WITH 语句并不熟悉。
    • 小问题,当我更改时间时,最后 4 行发生在同一小时内,他们 Rosalia Maher 等被报告了两次,并且由于某种原因单独报告了 Keisha Seip。我不认为 per1h 必须具有相同的类别和相同的团队。但我会自己调查一下,我只是想让你知道。
    猜你喜欢
    • 2021-08-29
    • 1970-01-01
    • 2020-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多