【问题标题】:How to break down smalldatetime into year, month, day indexes?如何将 smalldatetime 分解为年、月、日索引?
【发布时间】:2011-10-08 16:42:12
【问题描述】:

我使用的是 SQL Server 2008。

我的数据库中有一些日期,我“认为”我想将它们分解成更小的部分。日期是生日和死亡日。我希望能够通过查询出生于 10 月或 5 月 12 日或 1945 年的人来输出它们。

有人告诉我,这样做的典型方法是获取一个日期并将其分成更小的部分,然后将日期的每一部分放入自己的列中,如下所示:

2001-03-12 00:00:00 // EventDate column

添加这些列:

2001 // EventYear column
03 // EventMonth column
12 // EventDay column

首先,这是一个好方法吗?如果是这样,第二,我能否以某种方式让 SQL Server 自动打破日期部分并将其放入自己的列中?

我会很感激想法和解决方案。

【问题讨论】:

  • 那张表有多少行数据?
  • 最多有 10,000 行分布在四到六个表中。我真的很想学习“正确”的方法来做到这一点。我不希望以任何旧的方式完成它。我已经可以用四五种“错误”的方式来做这件事了。我想知道专家会怎么做。
  • 分布在 4-6 张桌子上是什么意思?
  • 我会有四五张带日期的表格。每个表可能有 2,000 行。
  • 我认为没有理由指示 Erik 拆分每个日期时间列以查询 2000 条记录。

标签: sql sql-server


【解决方案1】:

我建议您将其保留为日期列,然后在查询中使用DatePart 来过滤结果。

Select * from TABLEX
where DatePart(YEAR,EventDate) = 1945

【讨论】:

  • 当查询是针对 5 月 12 日时,这将如何执行?
  • 这是处理日期时间列操作的正确方法。除非您谈论的是具有数百万条记录且性能极其重要的数据库,否则将日期复制到多个列中几乎没有意义。此功能成本低,性能良好。
  • 我当然不会有数百万个约会,可能只有几千个。我想这样做,就好像有一百万个约会一样。我宁愿写一个像 select * from DateTable where Year = 1945 这样的查询,也不愿在每个查询中都做日期部分。
  • 使用 datepart 的主要好处是您无需在每次想要以不同方式对数据进行切片时都考虑创建新列。例如...如果您决定要了解星期六发生的所有事件,则无需为星期几创建另一列,只需使用 datepart weekday。
  • 主要的缺点是每个查询都将是一个表扫描,可能除了按顺序包括年、月、日等的查询(我不知道)不知道 DatePart 是否是 sargable,但部分查询肯定不是。)
【解决方案2】:

听起来业务需求不是很固化。出于什么原因,您需要拆分日期的不同部分?如果你不需要,那我不会。

但是,如果您确实有必要这样做,那么我会使用持久化的计算列。插入会产生一些开销,但由于不会对现有数据进行任何更新(您的出生日期和死亡日期不会更改),因此您不会在 SELECT 上看到任何性能开销。

类似这样的:

create table DateTest
(
    SomeDate datetime not null,
    SomeYear as datepart(yy, somedate) persisted,
    SomeMonth as datepart(mm, somedate) persisted,
    SomeDay as datepart(dd, somedate) persisted
)

【讨论】:

  • +1 用于计算列,但不要忘记添加索引,否则无论如何您都会使用列进行表扫描。并且每年的计算列并不是真正必要的。您可以直接使用日期列。
  • 有趣的解决方案。这超出了我的经验水平,但我将对其进行研究并牢记在心。谢谢!
【解决方案3】:

这就是我的工作。

我有一个表“lib.Dates”。它有一个 DATE 作为主键。

它还有其他列,其中包含截至该日期的其他信息。例如,一个月中的某天、月末的一天、一年中的一周等。

将这个日期表与日期结合起来可以让我: * 获取所有日期的列表(例如,按日期对每个人的销售额进行分组将没有零销售额的条目,这样就可以了) * 做一些有趣的事情,比如一年中第 23 周的所有日期,这通常更难获得。

这是我存储过程每天维护的许多此类表的一部分(-3 年,+5 年)。

【讨论】:

  • 您的意思是一个Calendar 表,每个其他具有date 字段的表都可以将其引用为FOREIGN KEY?那么,没有其他表需要持久化的索引视图吗?如果是,请向我 +1。
  • 是的,完全正确。它也属于我维护的一个库项目——我有时会在这里添加新表。尤其是 join 有时非常好(因为它让我拥有所有日期的列表,而不仅仅是有数据的日期)。
  • 是的,SO中时不时出现类似的问题,“查找所有没有下单的日期”。
  • TomTom,这是一个有趣的解决方案,但对我来说太过分了。不过,我感谢您向我介绍这个想法。
猜你喜欢
  • 1970-01-01
  • 2021-10-11
  • 1970-01-01
  • 2015-02-23
  • 1970-01-01
  • 2010-11-17
  • 1970-01-01
  • 2019-08-03
  • 1970-01-01
相关资源
最近更新 更多