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

发布于 2024-12-04 05:21:04 字数 80 浏览 1 评论 0原文

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

Is it possible to write a Microsoft SQL query that will group by a datetime data-type but ignoring the time part such as the hour and minute?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

戏剧牡丹亭 2024-12-11 05:21:04

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

GROUP BY CAST(YourCol AS Date)

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

GROUP BY DATEDIFF(DAY, 0, YourCol)

但是,这些都无法利用这样一个事实:按 datetime 排序的 YourCol 上的索引也将按 date 排序 因此使用流聚合而不进行排序操作。

在 SQL Server 2008+ 上,您可能会考虑索引 (date,time) 而不是 datetime 来促进此类查询。

要么简单地将其存储为两个单独的组件,并可能提供一个重新组合各部分的计算列(datetime2 的存储方式与 datetime< /code> 因此,除非附加列将 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

在此处输入图像描述

If you are on SQL Server 2008 this is simple.

GROUP BY CAST(YourCol AS Date)

For previous versions you can use

GROUP BY DATEDIFF(DAY, 0, YourCol)

However neither of these will be able to leverage the fact that an index on YourCol that is ordered by datetime will also be ordered by date and thus use a stream aggregate without a sort operation.

On SQL Server 2008+ you might consider indexing (date,time) rather than datetime to facilitate this type of query.

Either by simply storing it as two separate components and possibly providing a calculated column that recombines the parts (a datetime2 is stored the same as a date and a time so this won't consume any more space except for if the additional column pushes the NULL_BITMAP onto a new byte.).

CREATE TABLE T
(
YourDateCol date,
YourTimeCol time,
YourDateTimeCol AS  DATEADD(day, 
                            DATEDIFF(DAY,0,YourDateCol), 
                            CAST(YourTimeCol AS DATETIME2(7)))
/*Other Columns*/
)

Or alternatively you could store it combined in the base table and have the indexes use calculated columns that split it out.

An example of this approach

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

enter image description here

可是我不能没有你 2024-12-11 05:21:04

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

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

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 上放置一个索引,分组(和搜索)将会很多快点。

If you have a large table and want grouping to happen fast, you cannot rely grouping on an expression.

Create an additional datetime column on your table and have it filled by a trigger that calculates the base date from you "real" date:

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

Then put an index on EffectiveDate and grouping (and searching) will be a lot faster.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文