Фильтровать столбцы даты и времени в SQL Server - PullRequest
0 голосов
/ 03 июля 2018

У меня есть столбец даты и времени, который имеет интервал 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 минут), особенно в таблице с тысячами строк?

Привет, @ Андреа, спасибо за это. У меня есть пара вопросов. Что означает «д»? и когда я переписываю запрос как

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 |
+-----------+-------------------------+-----------------------+

Любая причина, по которой

Ответы [ 2 ]

0 голосов
/ 03 июля 2018

Вы можете использовать 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

Результаты:

enter image description here

Так что вы должны использовать это так:

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

Выход:

enter image description here

Здесь вы можете проверить, что результаты рассчитаны правильно.

0 голосов
/ 03 июля 2018

Поскольку вы находитесь в 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
...