代码之家  ›  专栏  ›  技术社区  ›  regex

MS SQL仅显示日期,不显示时间

  •  49
  • regex  · 技术社区  · 16 年前

    问题

    大家好,

    很长一段时间以来,我一直对使用T-SQL构建DateTime SQL类型感到困惑。从本质上讲,我想取一个DateTime值,比如2008-12-1 14:30:12,并将其设置为2008年12月1日00:00:00。我们为报告运行的许多查询在WHERE子句中使用了日期值,但我要么有一个开始和结束日期值,并使用BETWEEN,要么我找到了其他方法。

    目前,我正在使用以下内容: WHERE CAST(CONVERT(VARCHAR, [tstamp], 102) AS DATETIME) = @dateParam

    然而,这似乎有点笨拙。我希望会有更简单的东西,比如 CAST([tstamp] AS DATE)

    网上有些地方建议使用DATEPART()函数,但我最终得到了这样的结果:

    
    WHERE DATEPART(year, [tstamp]) = DATEPART(year, @dateParam)
    AND DATEPART(month, [tstamp]) = DATEPART(month, @dateParam)
    AND DATEPART(day, [tstamp]) = DATEPART(day, @dateParam)
    
    

    也许我过于关心一些小事,如果是这样,请告诉我。我只是想确保我写的东西尽可能高效。我想消除任何薄弱环节。

    有什么建议吗?

    谢谢,
    C

    解决方案

    感谢大家的宝贵反馈。很多有用的信息。我将围绕我们的功能进行更改,以消除操作员左侧的功能。尽管我们的大多数日期列不使用索引,但这可能仍然是一种更好的做法。

    12 回复  |  直到 16 年前
        1
  •  96
  •   mattmc3    13 年前

    如果您使用的是SQL Server 2008,它现在内置了此功能,请参阅 books online

    CAST(GETDATE() AS date)

        2
  •  38
  •   SQLMenace    16 年前

    这对性能非常不利,看看 Only In A Database Can You Get 1000% + Improvement By Changing A Few Lines Of Code

    操作员左侧的功能不好

    这是你需要做的

    declare @d datetime
    select @d =  '2008-12-1 14:30:12'
    
    where tstamp >= dateadd(dd, datediff(dd, 0, @d)+0, 0)
    and tstamp < dateadd(dd, datediff(dd, 0, @d)+1, 0)
    

    运行此程序看看它有什么作用

    select dateadd(dd, datediff(dd, 0, getdate())+1, 0)
    select dateadd(dd, datediff(dd, 0, getdate())+0, 0)
    
        3
  •  11
  •   Joel Coehoorn    16 年前

    其他人发布的日期函数是处理此问题的最正确方法。

    然而,有趣的是,你提到了“地板”这个词,因为有一个小黑客会跑得更快:

    CAST(FLOOR(CAST(@dateParam AS float)) AS DateTime)
    
        4
  •  8
  •   DarthJDG chetan borse    14 年前

    CONVERT(date, GETDATE()) CONVERT(time, GETDATE()) 适用于SQL Server 2008。我对2005年不太确定。

        5
  •  6
  •   Sameer    14 年前

    这个怎么样?

    SELECT DATEADD(dd, DATEDIFF(dd,0,GETDATE()), 0)
    
        6
  •  1
  •   Lusid    16 年前

    是的,T-SQL有时会感觉非常原始,正是这样的事情经常促使我用我选择的语言(如C#)做很多逻辑。

    然而,当你出于性能原因绝对需要在SQL中做这些事情时,你最好的选择是创建函数来容纳这些“算法”

    看看这篇文章。他沿着这些思路提供了很多方便的SQL函数,我认为这些函数会对你有所帮助。

    http://weblogs.sqlteam.com/jeffs/archive/2007/01/02/56079.aspx

        7
  •  1
  •   Sam Saffron James Allen    16 年前

    小心这里,如果你使用任何长的线 WHERE CAST(CONVERT(VARCHAR, [tstamp], 102) AS DATETIME) = @dateParam 它将强制对表进行扫描,并且不会对该部分使用索引。

    一种更简洁的方法是定义一个计算列

    create table #t (
        d datetime, 
    
        d2 as 
            cast (datepart(year,d) as varchar(4)) + '-' +
            right('0' + cast (datepart(month,d) as varchar(2)),2) + '-' + 
            right('0' + cast (datepart(day,d) as varchar(2)),2) 
    ) 
    -- notice a lot of care need to be taken to ensure the format is comparable. (zero padding)
    
    insert #t 
    values (getdate())
    
    create index idx on #t(d2)
    
    select d2, count(d2) from #t 
    where d2 between '2008-01-01' and '2009-01-22'
    group by d2
    -- index seek is used
    

    这样你就可以直接检查d2列,并使用索引,而不必费心进行转换。

        8
  •  1
  •   DarthJDG chetan borse    14 年前
    DATEADD(d, 0, DATEDIFF(d, 0, [tstamp]))
    

    编辑:虽然这将删除日期时间的时间部分,但它也会使条件 non SARGable 。如果这对此查询很重要,则索引视图或between子句更合适。

        9
  •  0
  •   Xander    16 年前

    或者,您可以使用

    declare @d datetimeselect
    @d =  '2008-12-1 14:30:12'
    where tstamp 
      BETWEEN dateadd(dd, datediff(dd, 0, @d)+0, 0) 
      AND dateadd(dd, datediff(dd, 0, @d)+1, 0)
    
        10
  •  0
  •   Rob Boek    14 年前

    这是一个查询,将返回几天内的所有结果。

    DECLARE @startDate DATETIME
    DECLARE @endDate DATETIME
    
    SET @startDate = DATEADD(day, -30, GETDATE())
    SET @endDate = GETDATE()
    
    SELECT *
    FROM table
    WHERE dateColumn >= DATEADD(day, DATEDIFF(day, 0, @startDate), 0)
      AND dateColumn <  DATEADD(day, 1, DATEDIFF(day, 0, @endDate))
    
        11
  •  0
  •   DarthJDG chetan borse    14 年前

    FWW,多年来我一直在做和你一样的事情

    CAST(CONVERT(VARCHAR, [tstamp], 102) AS DATETIME) = @dateParam 
    

    在我看来,这是在灵活性、速度和易用性方面节省时间的更好方法之一。(对不起)。建议的一些UDF函数可能很有用,但UDF在处理较大的结果集时可能会很慢。

        12
  •  -1
  •   DarthJDG chetan borse    14 年前
    WHERE DATEDIFF(day, tstamp, @dateParam) = 0
    

    如果你不在乎时间,这应该能让你到达那里。

    这是为了回答在不关心时间的情况下比较两个值的日期的元问题。