【问题标题】:DATEDIFF with a number instead of a date带有数字而不是日期的 DATEDIFF
【发布时间】:2019-10-02 14:53:10
【问题描述】:

我在尝试理解 DATEDIFF 应该如何工作时遇到了一些麻烦。在某些情况下,我看到了一个 int 参数,而不是像下面的示例这样的有效日期:

/* Output is 119 */
SELECT DATEDIFF(year, 6, '2019/05/15');

/* Output is 6.227 */
SELECT DATEDIFF(week, 6, '2019/05/15');

在这种情况下,如何处理 6 号?什么意思?

谢谢!

【问题讨论】:

  • 隐式转换为datetime
  • 我敢说如果有人在使用它,他们根本就没有正确使用它。文档明确指出第二个参数是 startdate 并将所有日期类型列为有效参数。没有一个是 int。
  • 这种不幸的隐式转换是人们应该使用datetime2而不是datetime的原因
  • 我更关心使用该日期格式,而不是不受语言设置影响的日期格式。对于我们中的一些人来说,使用整数和直接数学是旧日期类型的一大优势。

标签: sql sql-server datediff dateadd


【解决方案1】:

这是implict data type conversion 的示例。 DATEDIFF() 允许将datetime 作为参数类型,因此6 隐式转换为datetimeDATEADD()0 转换为1900-01-01

SELECT DATEDIFF(year, 6, '2019/05/15');
SELECT DATEDIFF(week, 6, '2019/05/15');

其实是

SELECT DATEDIFF(year, DATEADD(day, 0, 6), '2019/05/15');
SELECT DATEDIFF(week, DATEADD(day, 0, 6), '2019/05/15');

【讨论】:

  • ...然后你仍然在DATEADD 中有一个隐式转换,所以也许重写它,因为0 也变成了——1900-01-01
  • 虽然这都是正确的,但我对“DATEDIFF 允许日期时间作为参数类型,因此 6 隐式转换为日期时间”存在问题。 DATEDIFF 还允许 DATE、DATETIMEOFFSET、DATETIME2、SMALLDATETIME、TIME。那么为什么它不隐式转换为其中之一呢?它是否转换为不会出错的任何内容?
  • @JeroenMostert 感谢您的说明,我已经更新了答案。
  • @HoneyBadger Data types date, 'time', 'datetime2' do not allow conversion from integer, so datetime` 似乎是唯一可能的隐式转换候选对象。
  • @HoneyBadger:如果你真的想知道,可以单独提出一个问题。在 T-SQL 中,DATEDIFF 似乎遵循它自己的规则。 (例如,虽然INTDATETIME2 之间的转换是不允许的,但DATEDIFF(DAY, SYSDATETIME(), 0) 允许的,因此遵循隐式转换/优先规则并不是一件简单的事情。)
【解决方案2】:

如果仅将时间值分配给日期数据类型变量,DATEDIFF 会将缺失日期部分的值设置为默认值:1900-01-01。 所以,下面的 sn-p 返回 119(6 = 1990 年 1 月 7 日)

SELECT DATEDIFF(year, '1900/01/07', '2019/05/15');

【讨论】:

  • 你的第一句话是正确的但无关紧要,因为6根本不是时间值。 DATETIME 的内部表示使用小数部分来表示时间。原始语句等价于DATEDIFF(year, '1900-01-07', '2019-05-15')(当然也产生 119)。
猜你喜欢
  • 1970-01-01
  • 2022-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-13
  • 2020-04-21
  • 1970-01-01
相关资源
最近更新 更多