筛选 SQL 服务器中的日期时间列
Filter datetime columns in SQL Server
我有一个日期时间列,在下一个数据之间有 5 分钟的间隔,但是我想看看该列是否包含任何小于 5 分钟的时间间隔,尤其是 5 秒。
例如:
- 一个日期会读作
2018-05-04 19:21:46.000
- 下一行将显示为
2018-05-04 19:26:46.000
- 和
2018-05-04 19:31:46.000
。
但是,我们有时会得到这样的行:
2018-05-04 19:36:46.000
- 然后
2018-05-04 19:36:51.000
- 然后
2018-05-04 19:36:56.000
什么 SQL 脚本最好过滤列以区分错误数据(5 秒间隔)和正确数据(5 分钟间隔),尤其是在 table 有数千个行数?
嗨@Andrea,谢谢。我有一些问题。 'q' 代表什么?当我将查询重写为
SELECT ProductID, MyTimestamp, DATEDIFF(second, xMyTimestamp, MyTimestamp) as DIFFERENCE_IN_SECONDS
FROM (
SELECT *,
Lag(MyTimestamp) OVER (ORDER BY MyTimestamp, ProductID) as xMyTimestamp
FROM TableName
) q
WHERE xMyTimestamp IS NOT NULL and ProductID= 31928
我得到的结果没有准确计算时间。
+-----------+-------------------------+-----------------------+
| ProductID | MyTimestamp | DIFFERENCE_IN_SECONDS |
+-----------+-------------------------+-----------------------+
| 31928 | 2017-03-21 13:36:30.000 | 0 |
| 31928 | 2017-03-21 13:46:30.000 | 0 |
| 31928 | 2017-03-21 13:56:32.000 | 0 |
| 31928 | 2017-03-21 14:01:32.000 | 0 |
| 31928 | 2017-03-21 14:11:32.000 | 0 |
| 31928 | 2017-03-21 14:16:32.000 | 0 |
| 31928 | 2017-03-21 14:26:32.000 | 0 |
| 31928 | 2017-03-21 14:36:32.000 | 0 |
+-----------+-------------------------+-----------------------+
任何原因
因为你是 2014 年,你可以使用 LEAD
来比较一行的值和下一行的值。
declare @table table(id int identity(1,1), interval datetime)
insert into @table
values
('2018-05-04 19:21:46.000'),
('2018-05-04 19:26:46.000'),
('2018-05-04 19:31:46.000'),
('2018-05-04 19:36:46.000'),
('2018-05-04 19:36:51.000'),
('2018-05-04 19:36:56.000')
select
id
,interval
,issue_with_row = case
when
isnull(datediff(minute,interval,lead(interval) over (order by id, interval)),0) < 5
then 1
else 0
end
from @table
order by id
或者,如果您只想查看这些,
;with cte as(
select
id
,interval
,issue_with_row = case
when
isnull(datediff(minute,interval,lead(interval) over (order by id, interval)),0) < 5
then 1
else 0
end
from @table)
select *
from cte
where issue_with_row = 1
您可以使用 LAG
:
declare @tmp table(MyTimestamp datetime)
insert into @tmp values
('2018-05-04 19:21:46.000')
,('2018-05-04 19:26:46.000')
,('2018-05-04 19:31:46.000')
,('2018-05-04 19:36:46.000')
,('2018-05-04 19:36:51.000')
,('2018-05-04 19:36:56.000')
SELECT DATEDIFF(second, xMyTimestamp, MyTimestamp) as DIFFERENCE_IN_SECONDS
FROM (
SELECT *,
LAG(MyTimestamp) OVER (ORDER BY MyTimestamp) xMyTimestamp
FROM @tmp
) q
WHERE xMyTimestamp IS NOT NULL
结果:
所以你应该这样使用它:
SELECT DATEDIFF(second, xMyTimestamp, MyTimestamp) as DIFFERENCE_IN_SECONDS
FROM (
SELECT *,
LAG(MyTimestamp) OVER (ORDER BY MyTimestamp) xMyTimestamp
FROM [YOUR_TABLE_NAME_HERE]
) q
WHERE xMyTimestamp IS NOT NULL
编辑
这是另一个基于 OP 发布的新数据的示例:
declare @tmp table(ProductID int, MyTimestamp datetime)
insert into @tmp values
(31928, '2017-03-21 13:36:30.000')
,(31928, '2017-03-21 13:46:30.000')
,(31928, '2017-03-21 13:56:32.000')
,(31928, '2017-03-21 14:01:32.000')
,(31928, '2017-03-21 14:11:32.000')
,(31928, '2017-03-21 14:16:32.000')
,(31928, '2017-03-21 14:26:32.000')
,(31928, '2017-03-21 14:36:32.000')
SELECT ProductID
,MyTimestamp
,DATEDIFF(second, xMyTimestamp, MyTimestamp) AS DIFFERENCE_IN_SECONDS
FROM (
SELECT *
,Lag(MyTimestamp) OVER (
ORDER BY MyTimestamp
,ProductID
) AS xMyTimestamp
FROM @tmp
) q
WHERE xMyTimestamp IS NOT NULL
AND ProductID = 31928
输出:
Here您可以检查结果是否正确计算。
我有一个日期时间列,在下一个数据之间有 5 分钟的间隔,但是我想看看该列是否包含任何小于 5 分钟的时间间隔,尤其是 5 秒。
例如:
- 一个日期会读作
2018-05-04 19:21:46.000
- 下一行将显示为
2018-05-04 19:26:46.000
- 和
2018-05-04 19:31:46.000
。
但是,我们有时会得到这样的行:
2018-05-04 19:36:46.000
- 然后
2018-05-04 19:36:51.000
- 然后
2018-05-04 19:36:56.000
什么 SQL 脚本最好过滤列以区分错误数据(5 秒间隔)和正确数据(5 分钟间隔),尤其是在 table 有数千个行数?
嗨@Andrea,谢谢。我有一些问题。 'q' 代表什么?当我将查询重写为
SELECT ProductID, MyTimestamp, DATEDIFF(second, xMyTimestamp, MyTimestamp) as DIFFERENCE_IN_SECONDS
FROM (
SELECT *,
Lag(MyTimestamp) OVER (ORDER BY MyTimestamp, ProductID) as xMyTimestamp
FROM TableName
) q
WHERE xMyTimestamp IS NOT NULL and ProductID= 31928
我得到的结果没有准确计算时间。
+-----------+-------------------------+-----------------------+
| ProductID | MyTimestamp | DIFFERENCE_IN_SECONDS |
+-----------+-------------------------+-----------------------+
| 31928 | 2017-03-21 13:36:30.000 | 0 |
| 31928 | 2017-03-21 13:46:30.000 | 0 |
| 31928 | 2017-03-21 13:56:32.000 | 0 |
| 31928 | 2017-03-21 14:01:32.000 | 0 |
| 31928 | 2017-03-21 14:11:32.000 | 0 |
| 31928 | 2017-03-21 14:16:32.000 | 0 |
| 31928 | 2017-03-21 14:26:32.000 | 0 |
| 31928 | 2017-03-21 14:36:32.000 | 0 |
+-----------+-------------------------+-----------------------+
任何原因
因为你是 2014 年,你可以使用 LEAD
来比较一行的值和下一行的值。
declare @table table(id int identity(1,1), interval datetime)
insert into @table
values
('2018-05-04 19:21:46.000'),
('2018-05-04 19:26:46.000'),
('2018-05-04 19:31:46.000'),
('2018-05-04 19:36:46.000'),
('2018-05-04 19:36:51.000'),
('2018-05-04 19:36:56.000')
select
id
,interval
,issue_with_row = case
when
isnull(datediff(minute,interval,lead(interval) over (order by id, interval)),0) < 5
then 1
else 0
end
from @table
order by id
或者,如果您只想查看这些,
;with cte as(
select
id
,interval
,issue_with_row = case
when
isnull(datediff(minute,interval,lead(interval) over (order by id, interval)),0) < 5
then 1
else 0
end
from @table)
select *
from cte
where issue_with_row = 1
您可以使用 LAG
:
declare @tmp table(MyTimestamp datetime)
insert into @tmp values
('2018-05-04 19:21:46.000')
,('2018-05-04 19:26:46.000')
,('2018-05-04 19:31:46.000')
,('2018-05-04 19:36:46.000')
,('2018-05-04 19:36:51.000')
,('2018-05-04 19:36:56.000')
SELECT DATEDIFF(second, xMyTimestamp, MyTimestamp) as DIFFERENCE_IN_SECONDS
FROM (
SELECT *,
LAG(MyTimestamp) OVER (ORDER BY MyTimestamp) xMyTimestamp
FROM @tmp
) q
WHERE xMyTimestamp IS NOT NULL
结果:
所以你应该这样使用它:
SELECT DATEDIFF(second, xMyTimestamp, MyTimestamp) as DIFFERENCE_IN_SECONDS
FROM (
SELECT *,
LAG(MyTimestamp) OVER (ORDER BY MyTimestamp) xMyTimestamp
FROM [YOUR_TABLE_NAME_HERE]
) q
WHERE xMyTimestamp IS NOT NULL
编辑
这是另一个基于 OP 发布的新数据的示例:
declare @tmp table(ProductID int, MyTimestamp datetime)
insert into @tmp values
(31928, '2017-03-21 13:36:30.000')
,(31928, '2017-03-21 13:46:30.000')
,(31928, '2017-03-21 13:56:32.000')
,(31928, '2017-03-21 14:01:32.000')
,(31928, '2017-03-21 14:11:32.000')
,(31928, '2017-03-21 14:16:32.000')
,(31928, '2017-03-21 14:26:32.000')
,(31928, '2017-03-21 14:36:32.000')
SELECT ProductID
,MyTimestamp
,DATEDIFF(second, xMyTimestamp, MyTimestamp) AS DIFFERENCE_IN_SECONDS
FROM (
SELECT *
,Lag(MyTimestamp) OVER (
ORDER BY MyTimestamp
,ProductID
) AS xMyTimestamp
FROM @tmp
) q
WHERE xMyTimestamp IS NOT NULL
AND ProductID = 31928
输出:
Here您可以检查结果是否正确计算。