【问题标题】:Sql Server Select Only Date Part From DateTimeSql Server 从 DateTime 中仅选择日期部分
【发布时间】:2014-10-01 11:37:17
【问题描述】:

我在 Sql Server 中遇到问题,只能从 DateTime 中选择日期部分。

DateTime 的值为 2014-05-01 00:00:00.000。

如果尝试这个查询我没有错误并且输出是正确的:

SELECT CONVERT(VARCHAR(10),'2014-05-01 00:00:00.000',110)
2014-05-01

如果在 doTable 中尝试了其他查询:

SELECT
    TOP 100 *
FROM
    [n].[a2].[DOTABLE]
WHERE
    CONVERT(VARCHAR(10),data,110) > DATEADD(DAY, - 1, getdate())
ORDER BY
    data DESC;

我有这个错误:

SQL Server Error Messages - Msg 242 - 
The conversion of a char data type to a datetime data type 
resulted in an out-of-range datetime value.

SQL server 的版本是:

Microsoft SQL Server 2005 - 9.00.1399.06 (Intel X86)        
Oct 14 2005 00:33:37        
Copyright (c) 1988-2005 Microsoft Corporation       
Standard Edition on Windows NT 6.1 (Build 7600: )

我想我做得不对,但我知道为什么。

【问题讨论】:

  • 数据列中存储的日期格式是什么?
  • 数据列中存储的日期格式为datetime

标签: sql sql-server datetime


【解决方案1】:

我认为以下是做你想做的更好的方法:

where date >= dateadd(day, 0, datediff(day, 0, getdate()) - 1)

这会将当前日期截断为昨天的午夜,我猜这就是你真正想要的。

对于您的方法,请尝试使用格式 120:

SELECT TOP 100 *
FROM [n].[a2].[DOTABLE]
WHERE CONVERT(VARCHAR(10), data, 120) > DATEADD(DAY, - 1, getdate())
ORDER BY data DESC;

你可以在两边都这样做:

SELECT TOP 100 *
FROM [n].[a2].[DOTABLE]
WHERE CONVERT(VARCHAR(10), data, 120) > CONVERT(varchar(10), DATEADD(DAY, - 1, getdate()), 120)
ORDER BY data DESC;

此格式为 YYYY-MM-DD,便于比较。

然后,升级 SQL Server,并改用 date 数据类型。

【讨论】:

  • 谢谢,但您的查询输出为空,但我有数据2014-09-30 00:00:00.000
  • @AntonioMailtraq 。 . .我看不出这对我的回答有何影响。
  • 我个人喜欢 dateadd/datediff 方法,并且经常使用它。对于这种事情,子串只是感觉很脏。
  • @md4 。 . .就个人而言,我厌恶它。幸运的是,在 2008 年之前,我很少需要使用 SQL Server。
  • 我喜欢它的灵活性,它可以用于几乎任何时间单位(月、分钟、小时,甚至几周,但要小心),并且很容易适应group by 子句。当然,convert(date, ...) 更适合白天分辨率,但这就是它所能做的全部。
【解决方案2】:

在 SQL Server 2008 中验证了您的查询。它运行良好可能是与 SQL Server 2005 相关的特定问题,用于在 varchar 和日期时间之间进行转换。

您可以在此处添加对日期类型的显式转换

 SELECT
    TOP 100 *
FROM
    [n].[a2].[DOTABLE]
WHERE
    CAST( CONVERT(VARCHAR(10),data,110) as datetime) > DATEADD(DAY, - 1, getdate())

ORDER BY
    data DESC;

【讨论】:

    【解决方案3】:

    我的建议是使用以下转换将您不需要的日期部分(在这种情况下为时间)归零:

    declare @n int = datediff(day, 0, [some_datetime_col]);
    

    上述部分将返回自 SQL Server 纪元时间以来的天数,作为整数。然后,完成转换:

    select dateadd(day, @n, 0);
    

    这会增加天数,返回一个没有时间部分的datetime。将其应用于您的示例:

    where
        datediff(day, 0, data) > (datediff(day, 0, getdate()) - 1)
    

    在您的情况下,您不需要转换回datetime,因为它只是一个where 子句;您可以非常有效地比较整数并获得相同的结果。

    此方法的额外好处是您可以轻松地将其应用于月份(例如,获取月份的第一天)和年份。几周后需要更加小心,但这超出了此答案的范围。

    【讨论】:

      【解决方案4】:

      为什么要将日期转换为 varchar?

      试试这个查询

      SELECT TOP 100 *
      FROM [n].[a2].[DOTABLE]
      WHERE data > DATEADD(DAY, - 1, getdate())
      ORDER BY data DESC;
      

      【讨论】:

      • 谢谢,但您的查询输出为空,但我有数据2014-09-30 00:00:00.000
      • @AntonioMailtraq 如果您必须使用 00:00:00.000 捕捉日期,您可以将条件更改为 >= 或将 getdate() 更改为 CURRENT_TIMESTAMP
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-12
      • 2016-11-29
      • 1970-01-01
      • 2012-02-20
      相关资源
      最近更新 更多