【问题标题】:Get just the Date from grouping in select from DateTime column in SQL Server仅从 SQL Server 中的 DateTime 列中选择分组中获取日期
【发布时间】:2009-02-12 19:04:06
【问题描述】:

我需要根据日期对一些记录进行分组,但它是一个日期和时间字段,我需要忽略 is 的时间部分,只按日期部分分组 - 这是我的 SQL:

SELECT   
    AutoShipItems.CustomerID,AutoShipItems.NextOrderDate,
    Customer.FirstName,Customer.LastName, Customer.EmailAddress
FROM        
    AutoShipItems 
        INNER JOIN    Customer ON 
            AutoShipItems.CustomerID =Customer.CustomerID
WHERE     
    (AutoShipItems.NextOrderDate <= GETDATE())
GROUP BY 
    AutoShipItems.CustomerID, AutoShipItems.NextOrderDate, 
    Customer.FirstName, Customer.LastName, 
    Customer.EmailAddress
ORDER BY 
    AutoShipItems.NextOrderDate

【问题讨论】:

标签: sql-server sql-server-2005


【解决方案1】:

如果只是分组,你也可以将 datetime 表达式转换为 int。

简单的CAST(datetime AS int) 实际上将日期时间四舍五入到最接近的日期,而不是丢弃时间部分。于是,

CAST(datetime - 0.5 AS int)

另一种方式:

CAST(CAST(datetime AS float) AS int)

(与日期时间不同,浮点数在转换为 int 时会被截断。)

我更喜欢前者,因为它更短。不过,不确定哪个在性能方面更好。不过,这个问题可能只出现在非常大的数据数组上。

【讨论】:

    【解决方案2】:
    cast (x as date)
    

    year(x)
    month(x)
    day(x)
    

    【讨论】:

    • 日期不是 MS SQL Server 中定义的类型。但是年月日工作就好了。
    • 日期是一个已定义的类型 - 检查一下
    • DATE 是在 SQL2008 中定义的,而不是在 SQL2005 或更早版本中定义的
    • 看起来是目前为止最简洁的语法,也非常适合检查日期范围的上限。
    【解决方案3】:

    您可以将date 类型与convertcast 一起使用。

    convert(date, @x)
    

    cast(@x as date)
    

    【讨论】:

      【解决方案4】:

      你可以这样分组:

      cast(floor(cast(AutoShipItems.NextOrderDate as float)) as datetime)
      

      我把它放到一个用户定义的标量函数中以使其更容易:

      create function [dbo].[xfn_TrimTimeFromDateTime]
      (
          @date as datetime
      )
      returns datetime with schemabinding as
      begin
          --- Convert to a float, and get the integer that represents it.
          --- And then convert back to datetime.
          return cast(floor(cast(@date as float)) as datetime)
      end
      

      然后你会这样调用:

      GROUP BY
          AutoShipItems.CustomerID, 
          dbo.xfn_TrimTimeFromDateTime(AutoShipItems.NextOrderDate), 
          Customer.FirstName, Customer.LastName, Customer.EmailAddress
      

      请注意,您可能必须更改 SELECT 子句中的值,因为您现在按不同的东西进行分组。

      【讨论】:

      • 在我的 MS SQL Server 2005 版本中没有定义为类型
      • @mson:日期在 SQL Server 2005 中不是可识别的类型,正如其他一些回复中所指出的那样。
      【解决方案5】:

      这个呢:

      select convert(datetime, convert(varchar(10), getdate(), 112))
      

      【讨论】:

        【解决方案6】:

        请参阅this link 了解三个不同版本的仅日期函数。这是我最终使用的那个:

        CREATE FUNCTION [dbo].[fn_GetDateOnly]  ( @pInputDate    DATETIME )
        RETURNS DATETIME
        BEGIN
        
            RETURN CAST(CONVERT(VARCHAR(10), @pInputDate, 111) AS DATETIME)
        
        END
        

        【讨论】:

        • 但是,为什么使用 111(日语)而不是 112(iso)?
        • 因为ISO格式112没有标点符号,转换回datetime可能会猜到格式错误。我希望有一种 yyyy-mm-dd 没有时间的格式;那将是我的偏好。
        • 请注意 CONVERT(VARCHAR 删除时间的方法比 CAST(FLOOR(CAST 或 DATEADD(DATEDIFF 方法) 慢几倍参见:stackoverflow.com/questions/133081/…(我也进行过类似测试)
        • 其实只是在这里尝试了 SELECT CAST(CONVERT(VARCHAR(10), GetDate(), 111) AS DATETIME) ,但我的服务器配置出错了
        【解决方案7】:

        您也可以只使用普通的旧 SQL 转换函数。最后一个参数允许您提供预定义的日期格式,其中一些会删除时间。这是修改后的查询。

        SELECT    AutoShipItems.CustomerID, convert(nvarchar(10), AutoShipItems.NextOrderDate, 110) as NextOrderDate ,Customer.FirstName,Customer.LastName, 
                             Customer.EmailAddress
        FROM        AutoShipItems INNER JOIN
                             Customer ON AutoShipItems.CustomerID =Customer.CustomerID
        WHERE     (AutoShipItems.NextOrderDate <= GETDATE())
        GROUP BY AutoShipItems.CustomerID, convert(nvarchar(10), AutoShipItems.NextOrderDate, 110) , Customer.FirstName, Customer.LastName, 
                             Customer.EmailAddress
        ORDER BY AutoShipItems.NextOrderDate
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-02-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-06-11
          • 2014-11-12
          相关资源
          最近更新 更多