按日期时间分组忽略时间部分

时间:2011-09-13 22:36:53

标签: sql sql-server datetime time group-by

是否可以编写一个Microsoft SQL查询,该查询将按datetime数据类型进行分组,但忽略时间部分,例如小时和分钟?

2 个答案:

答案 0 :(得分:12)

如果您使用的是SQL Server 2008,这很简单。

GROUP BY CAST(YourCol AS Date)

对于以前的版本,您可以使用

GROUP BY DATEDIFF(DAY, 0, YourCol)

然而,这些都不能利用YourCol排序的datetime上的索引也将由date排序,因此使用流聚合而不是(date,time)排序操作。

在SQL Server 2008+上,您可以考虑将datetime而非datetime2编入索引,以方便此类查询。

通过简单地将其存储为两个单独的组件并可能提供重新组合部分的计算列(datetimeNULL_BITMAP相同,这样就赢了除了附加列将CREATE TABLE T ( YourDateCol date, YourTimeCol time, YourDateTimeCol AS DATEADD(day, DATEDIFF(DAY,0,YourDateCol), CAST(YourTimeCol AS DATETIME2(7))) /*Other Columns*/ ) 推送到新字节之外,不会消耗更多空间。)。

CREATE TABLE T
(
DT DATETIME2,
D AS CAST(DT AS DATE),
T AS CAST(DT AS TIME)
)

CREATE INDEX IX1 ON T(DT);

SELECT COUNT(*), 
       CAST(DT AS DATE)
FROM T
GROUP BY CAST(DT AS DATE)

CREATE INDEX IX2 ON T(D,T);

SELECT COUNT(*), 
       CAST(DT AS DATE)
FROM T
GROUP BY CAST(DT AS DATE)

DROP TABLE T

或者,您可以将它组合在基表中,并使索引使用计算出的列将其拆分出来。

这种方法的一个例子

{{1}}

enter image description here

答案 1 :(得分:1)

如果您有一个大型表并希望分组发生快速,则不能依赖于对表达式进行分组。

在您的表格上创建一个额外的日期时间列,并通过触发器填充它,从您“真实”日期计算基准日期:

UPDATE
  MyTable
SET
  EffectiveDate = DATEADD(DAY, 0, DATEDIFF(DAY, 0, t.RecordDate))
FROM
  MyTable t
  INNER JOIN inserted i ON i.RowID = t.RowID

然后在EffectiveDate上放一个索引,分组(和搜索)会快得多。