是否可以编写一个Microsoft SQL查询,该查询将按datetime
数据类型进行分组,但忽略时间部分,例如小时和分钟?
答案 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
编入索引,以方便此类查询。
通过简单地将其存储为两个单独的组件并可能提供重新组合部分的计算列(date
与time
和NULL_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}}
答案 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
上放一个索引,分组(和搜索)会快得多。