在t-sql中计数和分组

时间:2009-03-12 10:50:47

标签: sql-server tsql

我有一个看起来像这样的表

CREATE TABLE MyTable(
    [RecordID] [bigint] IDENTITY(1,1) NOT NULL,
    [PortName] [nvarchar](50) NULL,
    [ReceivedEvent] [datetime] NULL,
    [SentEvent] [datetime] NULL,
);

数据可以是

   RecordID | PortName | ReceivedEvent       | SentEvent
   1        | Port1    | 2009-10-20 10:20:00 | NULL
   2        | Port2    | NULL                | 2009-10-20 10:10:00
   3        | Port2    | NULL                | 2009-10-20 10:02:00
   4        | Port2    | NULL                | 2009-10-20 11:00:00

我现在需要对这个表格提出两个问题:

1)我需要计算按端口和日期(而不是时间)分组的行数。然而,日期是问题中的参数(在这种情况下,它可能是“2009-10-20”)。我还想要每小时的最后一次“活动”

   NumberOfRows | PortName | Hour | LastActivityInHour 
   2            | Port2    | 10   | 2009-10-20 10:10:00
   1            | Port2    | 11   | 2009-10-20 11:00:00
   1            | Port1    | 10   | 2009-10-20 10:20:00

2)我还需要一个问题做同样的事情,但按日分组。而且就像我说的传入参数一样。在这种情况下,它可能是“2009-10-20”

   NumberOfRows | PortName | LastActivityInDay 
   3            | Port2    | 2009-10-20 11:00:00
   1            | Port1    | 2009-10-20 10:20:00

1 个答案:

答案 0 :(得分:3)

由于您的数据模型未正确规范化,因此这比实际需要的更为丑陋。

SELECT
  COUNT(t.RecordID) NumberOfRows,
  t.PortName,
  t.EventHour,
  MAX(t.EventDateTime) LastActivityInHour
FROM
  (
    SELECT
      RecordID,
      PortName,
      COALESCE(ReceivedEvent, SentEvent) EventDateTime,
      DATEPART(hh, COALESCE(ReceivedEvent, SentEvent)) EventHour,
      DATEADD(dd, 0, DATEDIFF(dd, 0, COALESCE(ReceivedEvent, SentEvent))) EventDate
    FROM
      MyTable
  ) t
WHERE
  t.EventDate = DATEADD(dd, 0, DATEDIFF(dd, 0, @TheDateInQuestion))
GROUP BY
  t.PortName,
  t.EventHour
ORDER BY
  t.PortName,
  t.EventHour

用于进行按日期分组的SQL非常相似,我将把它作为练习给你。 ; - )

我确信还有其他方法可以获得相同的结果。在这里查看内部查询的内容将有助于整体查询。