我有一张包含以下数据的表格:
PersonalID | Date
193 | 2017-06-01 08:02:00
193 | 2017-06-01 08:03:00
193 | 2017-06-01 08:03:00
193 | 2017-06-01 08:04:00
193 | 2017-06-01 08:09:00
193 | 2017-06-01 09:01:00
193 | 2017-06-01 09:06:00
193 | 2017-06-01 09:08:00
我想选择日期差异大于10分钟的所有记录。
例如,根据这些数据,我想显示带日期的记录 '2017-06-01 08:02:00' 和 '2017-06-01 09:01:00'并忽略其他记录。
我可以通过distinct关键字忽略重复记录(具有相同日期),但我不知道如何比较记录并选择日期差异大于10分钟的记录。
我使用此查询来实现此目的,但它会返回错误的记录。
declare @space int = 10;
with aaa as (select main.ID, main.PersonalID, main.Date
from HZG_Traffic main
where exists(select * from HZG_Traffic tr
where tr.PersonalID = main.PersonalID and
ABS(DATEDIFF(MI, main.Date,tr.Date)) < @space and
ABS(DATEDIFF(MI, main.Date, tr.Date)) <> 0)
and main.PersonalID = 193)
Select * from aaa
where id not in
(select
MIN(ID)
from aaa
group by
PersonalID,
DATEPART(DAY, Date), DATEPART(MONTH, Date), DATEPART(YEAR, Date),
DATEPART(HOUR, Date))
order by Date desc
你能帮助我,还是你对这个问题有更好的了解?
感谢
更新:
感谢您提供解决方案,我使用的是SQL Server 2014。
答案 0 :(得分:2)
假设您使用的是SQL Server 2012或更高版本,则可以使用LAG&amp; LEAD功能......
IF OBJECT_ID('tempdb..#TestData', 'U') IS NOT NULL
DROP TABLE #TestData;
CREATE TABLE #TestData (
PersonalID INT NOT NULL,
SomeDate DATETIME2(0) NOT NULL
);
INSERT #TestData (PersonalID, SomeDate) VALUES
(193, '2017-06-01 08:02:00'),
(193, '2017-06-01 08:03:00'),
(193, '2017-06-01 08:03:00'),
(193, '2017-06-01 08:04:00'),
(193, '2017-06-01 08:09:00'),
(193, '2017-06-01 09:01:00'),
(193, '2017-06-01 09:06:00'),
(193, '2017-06-01 09:08:00');
-- SELECT * FROM #TestData td;
--==================================================
WITH
cte_LagLead AS (
SELECT
td.PersonalID, td.SomeDate,
LagMins = ABS(DATEDIFF(MINUTE, td.SomeDate, LAG(td.SomeDate, 1, td.SomeDate) OVER (PARTITION BY td.PersonalID ORDER BY td.SomeDate))),
LeadMins = DATEDIFF(MINUTE, td.SomeDate, LEAD(td.SomeDate, 1, td.SomeDate) OVER (PARTITION BY td.PersonalID ORDER BY td.SomeDate))
FROM
#TestData td
)
SELECT
ll.PersonalID, ll.SomeDate
FROM
cte_LagLead ll
WHERE
ll.LagMins > 10
OR
ll.LeadMins > 10;
结果...
PersonalID SomeDate
----------- ---------------------------
193 2017-06-01 08:09:00
193 2017-06-01 09:01:00
答案 1 :(得分:0)
这实际上取决于您使用的SQL Server版本。以下是两个解决方案,一个适用于SQL Server 2012及更高版本,另一个适用于SQL Server 2008及更高版本。
第一个是SQL 2008及更高版本:
const expected = {/* very large object */}
test('returns data from `server/index.js` and it contains an array containing the `expected` object', () => {
expect(data.els[4]).toEqual(
expect.objectContaining(expected)
)
})
这个适用于SQL 2012及更高版本:
/* Populating the temp table with the data */
DECLARE @HZG_Traffic TABLE
(PersonalID INT,Date DATETIME);
INSERT INTO @HZG_Traffic (PersonalID,Date) VALUES (193,'2017-06-01 09:08:00');
INSERT INTO @HZG_Traffic (PersonalID,Date) VALUES (193,'2017-06-01 08:02:00');
INSERT INTO @HZG_Traffic (PersonalID,Date) VALUES (193,'2017-06-01 08:03:00');
INSERT INTO @HZG_Traffic (PersonalID,Date) VALUES (193,'2017-06-01 08:03:00');
INSERT INTO @HZG_Traffic (PersonalID,Date) VALUES (193,'2017-06-01 08:04:00');
INSERT INTO @HZG_Traffic (PersonalID,Date) VALUES (193,'2017-06-01 08:09:00');
INSERT INTO @HZG_Traffic (PersonalID,Date) VALUES (193,'2017-06-01 09:01:00');
INSERT INTO @HZG_Traffic (PersonalID,Date) VALUES (193,'2017-06-01 09:06:00');
/* Start with a CTE to number each record for the PersonalID */
WITH main AS (
SELECT
ROW_NUMBER() OVER(PARTITION BY ht.PersonalID ORDER BY ht.Date) AS Row_No
,ht.PersonalID
,ht.Date
FROM @HZG_Traffic AS ht
)
SELECT
main.PersonalID
,main.Date
FROM main
/* Self-join to get the previous record */
LEFT JOIN main AS prev ON main.PersonalID = prev.PersonalID AND main.Row_No-1 = prev.Row_No
/* Another self join to get the next record */
LEFT JOIN main AS nex ON main.PersonalID = nex.PersonalID AND main.Row_No+1 = nex.Row_No
/* Have the OR clause so it will return both records */
WHERE 10 <= DATEDIFF(MINUTE, main.Date, nex.Date)
OR 10 <= DATEDIFF(MINUTE, prev.Date,main.Date);
答案 2 :(得分:0)
你说你想要2017-06-01 08:02:00.000
和2017-06-01 09:01:00.000
,如果是这样,你可以尝试这样的事情。
SELECT *
FROM HZG_Traffic t1
CROSS APPLY (
SELECT MIN([Date]) AS MinDate
FROM HZG_Traffic t2
WHERE t1.PersonalID = t2.PersonalID
AND DATEDIFF(Minute, t2.[Date], t1.[Date]) < 10) t2
WHERE t1.[Date] = t2.MinDate