代码之家  ›  专栏  ›  技术社区  ›  Matt Howells

SQL Server中从日期+时间获取日期的最有效方法?

  •  72
  • Matt Howells  · 技术社区  · 16 年前

    在MS SQL 2000和2005中,给定诸如“2008-09-25 12:34:56”之类的日期时间,获取仅包含“2008-09-25”的日期时间的最有效方法是什么?

    复制 here .

    11 回复  |  直到 7 年前
        1
  •  115
  •   Tomas    16 年前

    我必须承认我以前从未见过马特展示的地板浮子转换。我必须测试一下。

    我测试了一个纯select(它将返回日期和时间,这不是我们想要的)、这里的主要解决方案(floor)、这里提到的一个常见的“幼稚”解决方案(stringconvert)和我正在使用的解决方案(因为我认为它是最快的)。

    我在测试服务器MS SQL server 2005上测试了这些查询,该服务器运行在Win 2003 SP2服务器上,Xeon 3GHz CPU运行在最大内存(32位,约为3.5 Gb)上。这是我所在的夜晚,机器几乎空载空转。这一切都是我一个人做的。

    下面是我的测试运行日志,它从一个包含时间戳的大表中选择,时间戳一直到毫秒级。此特定数据集包括2.5年以上的日期。这个表本身有超过1.3亿行,所以我把行数限制在前100万行。

    SELECT TOP 1000000 CRETS FROM tblMeasureLogv2 
    SELECT TOP 1000000 CAST(FLOOR(CAST(CRETS AS FLOAT)) AS DATETIME) FROM tblMeasureLogv2
    SELECT TOP 1000000 CONVERT(DATETIME, CONVERT(VARCHAR(10), CRETS, 120) , 120) FROM tblMeasureLogv2 
    SELECT TOP 1000000 DATEADD(DAY, DATEDIFF(DAY, 0, CRETS), 0) FROM tblMeasureLogv2
    

    SQL Server解析和编译时间:CPU时间=0毫秒,运行时间=1毫秒。

    SQL Server执行时间:CPU时间=422毫秒,运行时间=33803毫秒。

    (1000000行受影响)表“tblMeasureLogv2”。扫描计数1,逻辑读取4752,物理读取0,预读0,lob逻辑读取0,lob物理读取0,lob预读0。

    SQL Server执行时间:CPU时间=625毫秒,运行时间=33545毫秒。

    (1000000行受影响)表“tblMeasureLogv2”。扫描计数1,逻辑读取4752,物理读取0,预读0,lob逻辑读取0,lob物理读取0,lob预读0。

    SQL Server执行时间:CPU时间=1953毫秒,运行时间=33843毫秒。

    SQL Server执行时间:CPU时间=531毫秒,运行时间=33440毫秒。SQL Server解析和编译时间:CPU时间=0毫秒,运行时间=1毫秒。

    我们在这里看到了什么?

    Pure-Select:  422
    Floor-cast:   625
    String-conv: 1953
    DateAdd:      531  
    

    从这一点来看,DateAdd(至少在这个特殊情况下)比floor cast方法稍微快一点。

    我的服务器上有什么奇怪的东西吗?

        2
  •  25
  •   George Mastros    16 年前
    Select DateAdd(Day, DateDiff(Day, 0, GetDate()), 0)
    

    DateDiff(Day,0,GetDate())与DateDiff(Day,'1900-01-01',GetDate())相同

    由于DateDiff返回一个整数,因此您将获得自1900年1月1日以来经过的天数。然后将该整数天数添加到1900年1月1日。净效果是去除时间成分。

    Select  DateAdd(Year, DateDiff(Year, 0, GetDate()), 0)
    Select  DateAdd(Quarter, DateDiff(Quarter, 0, GetDate()), 0)
    Select  DateAdd(Month, DateDiff(Month, 0, GetDate()), 0)
    Select  DateAdd(Day, DateDiff(Day, 0, GetDate()), 0)
    Select  DateAdd(Hour, DateDiff(Hour, 0, GetDate()), 0)
    Select  DateAdd(Second, DateDiff(Second, '20000101', GetDate()), '20000101')
    

    最后一个,几秒钟,需要特殊处理。如果你使用1900年1月1日,你会得到一个错误。

    两个datetime列的差异导致运行时溢出。

        3
  •  12
  •   Matt Howells    16 年前
    select cast(floor(cast(@datetime as float)) as datetime)
    

    之所以有效,是因为将datetime强制转换为float会给出自1900年1月1日以来的天数(包括一天的分数)。它删除了小数天,并保留了整数天,然后可以将其转换回datetime。

        4
  •  7
  •   Hadi    7 年前

    在SQL server 2012中使用

    select cast(getdate() as date)
    
        5
  •  1
  •   Lloyd Powell binku    12 年前
    select cast(getdate()as varchar(11))as datetime
    
        6
  •  0
  •   Erick B    16 年前

    要获取YYYY-MM-DD,请使用:

    select convert(varchar(10), getdate(), 120)
    

    哎呀,他想要的是日期时间而不是字符串。与Oracle中的TRUNC()等效。您可以将我发布的内容追溯到DateTime:

    select convert(datetime, convert(varchar(10), getdate(), 120) , 120)
    
        7
  •  0
  •   Community Mofi    7 年前

    CONVERT、FLOOR和DATEDIFF将执行相同的操作。

    How to return the date part only from a SQL Server datetime datatype

        8
  •  0
  •   BlackWasp    16 年前

    下面的链接中介绍了三种方法。我还没有对它们进行性能测试以确定哪一个最快。

    http://www.blackwasp.co.uk/SQLDateFromDateTime.aspx

        9
  •  0
  •   Andrew dh    14 年前

    CAST(FLOOR(CAST(yourdate AS DECIMAL(12, 5))) AS DATETIME) 目前表现最好。你可以看到证据&测试时间 getting the date without time in sql server

        10
  •  -1
  •   Rafael    13 年前

    SELECT CAST(CASt(GETDATE() AS int) AS DATETIME)

        11
  •  -1
  •   Hadi    7 年前
    CONVERT(VARCHAR(10), GETDATE(), 120) AS [YYYY-MM-DD]