使用SQL Server 2005我使用UNION从一组两个表中选择DATETIME。其中许多非常接近:例如:
2016-01-29 10:28:57.540
2016-01-29 10:28:57.647
2016-01-29 11:23:18.193
2016-01-29 11:23:18.240
在这个例子中,我想回来
2016-01-29 10:28:57.000
2016-01-29 11:23:18.000
使用某些日期/转换功能删除ms部分很容易。但是,如果我们得到以下内容:
2016-01-29 10:18:58.105
2016-01-29 10:18:57.952
2016-01-29 11:13:18.193
2016-01-29 11:13:18.240
当我只想要2:
时,我会得到3个日期时间2016-01-29 10:18:58.000
2016-01-29 10:18:57.000
2016-01-29 11:13:18.000
而不是:
2016-01-29 10:18:58.000
2016-01-29 11:13:18.000
2016-01-29 10:18:58.105和2016-01-29 10:18:57.952不到一秒钟。
所以问题是我如何将DATETIME值组合在一起呢?
答案 0 :(得分:3)
MS SQL 2005更新
DECLARE @TestDate AS TABLE (
dt DATETIME NOT NULL
)
INSERT INTO @TestDate (dt)
VALUES
('2016-01-29 10:18:58.105')
,('2016-01-29 10:18:57.952')
,('2016-01-29 11:13:18.193')
,('2016-01-29 11:13:18.240')
;WITH IdDt AS (
SELECT Id = ROW_NUMBER() OVER (ORDER BY dt)
,dt
FROM @TestDate)
SELECt IdDt.dt
FROM IdDt
LEFT JOIN IdDt LagDt ON IdDt.ID = LagDt.ID + 1
WHERE CASE WHEN DATEDIFF(MILLISECOND, LagDt.dt, IdDt.dt) < 1000 Then 0 ELSE 1 END = 1
MS SQL Server 2012 +
DECLARE @TestDate AS TABLE (
dt DATETIME NOT NULL
)
INSERT INTO @TestDate (dt)
VALUES
('2016-01-29 10:18:58.105')
,('2016-01-29 10:18:57.952')
,('2016-01-29 11:13:18.193')
,('2016-01-29 11:13:18.240')
SELECT dt
FROM (
SELECT dt, CASE WHEN DATEDIFF(MILLISECOND, LAG(dt) OVER (ORDER BY dt), dt) < 1000 Then 0 ELSE 1 END ToRemove
FROM @TestDate
) Filter
WHERE ToRemove = 1;
答案 1 :(得分:1)
决定如何修剪微秒,然后按选择的功能分组
select
DT,
-- Round down to nearest second
DT_Floor_MS =
dateadd(ms,-datepart(ms,a.DT),a.DT),
-- Round up to nearest second
DT_Ceiling_MS =
dateadd(ms,(1000-datepart(ms,a.DT))%1000,a.DT),
-- Round to nearest second
DT_Round_Off_MS =
dateadd(ms,500-((datepart(ms,a.DT)+500)%1000),a.DT)
from
(select --test data
'2016-01-29 10:28:57.540' DT union all select
'2016-01-29 10:28:57.647'union all select
'2016-01-29 11:23:18.193'union all select
'2016-01-29 11:23:18.240' ) a
DT DT_Floor_MS DT_Ceiling_MS DT_Round_Off_MS
2016-01-29 10:28:57.540 January, 29 2016 10:28:57 January, 29 2016 10:28:58 January, 29 2016 10:28:58
2016-01-29 10:28:57.647 January, 29 2016 10:28:57 January, 29 2016 10:28:58 January, 29 2016 10:28:58
2016-01-29 11:23:18.193 January, 29 2016 11:23:18 January, 29 2016 11:23:19 January, 29 2016 11:23:18
2016-01-29 11:23:18.240 January, 29 2016 11:23:18 January, 29 2016 11:23:19 January, 29 2016 11:23:18
&#13;
select
dateadd(ms,(1000-datepart(ms,a.DT))%1000,a.DT)
-- Round to nearest second
from
(select --test data
'2016-01-29 10:28:57.540' DT union all select
'2016-01-29 10:28:57.647'union all select
'2016-01-29 11:23:18.193'union all select
'2016-01-29 11:23:18.240' ) a
group by
dateadd(ms,(1000-datepart(ms,a.DT))%1000,a.DT)
-- Round to nearest second
2016-01-29 10:28:58.000
2016-01-29 11:23:19.000
答案 2 :(得分:0)
为我的目的找到答案:
SELECT t1.UpdatedDateTime
FROM MyTable t1
LEFT JOIN MyTable t2 ON t1.UpdatedDateTime > t2.UpdatedDateTime AND t1.UpdatedDateTime < DATEADD(SECOND,1,t2.UpdatedDateTime)
WHERE t2.UpdatedDateTime IS NULL
将表格连接在一起只会带回另一行的行,并且在下一秒内有一段时间。
答案 3 :(得分:0)
最简单,最直接的方法是使用日期时间第二近似值的区别如下:
SELECT DISTINCT DATEADD(MILLISECOND, 500 - DATEPART(MILLISECOND, TimeField + '00:00:00.500'),TimeField) FROM T1