SQL "Where In" 用于空子查询
SQL "Where In" for empty subquery
我有以下查询,目的是显示每条记录到下一条记录的时间
数据:
gid time name
1010883478 29/03/2016 0:00:02 John
1010883527 29/03/2016 0:00:04 John
1010883578 29/03/2016 0:00:06 John
SQL:
SELECT A.[gid]
,A.[time]
,A.[name]
,(B.[time] - A.[time]) as timeTilNext
FROM [location] A CROSS JOIN [location] B
WHERE B.[gid] IN (
SELECT MIN(C.[gid])
FROM [location] C
WHERE C.[gid] > A.[gid] AND C.[name] = A.[name] )
ORDER BY A.[gid]
当前输出:
gid time name timeTilNext
1010883478 2016-03-29 00:00:02.000 John 1900-01-01 00:00:02.000
1010883527 2016-03-29 00:00:04.000 John 1900-01-01 00:00:02.000
预期输出:
gid time name timeTilNext
1010883478 2016-03-29 00:00:02.000 John 1900-01-01 00:00:02.000
1010883527 2016-03-29 00:00:04.000 John 1900-01-01 00:00:02.000
1010883578 2016-03-29 00:00:06.000 John -1 (or whatever)
但是,它没有显示给定 [name] 的最高 [gid] 的记录(仅第二高)。
我希望最高 [gid] 的 timeTilNext 显示 -1,表示没有更多事件。
关于如何修改我的查询有什么想法吗?
select
*,-1 as 'time until next ' from location t1
where time=(select max(time) from location t2 where t1.name=t2.name) b
在 SQL Server 2012 中,您可以使用 LEAD
window 函数获取 "next" 行的值。
DECLARE @location TABLE ([gid] int, [time] datetime, [name] varchar(50));
INSERT INTO @location ([gid], [time], [name]) VALUES
(1010883478, '2016-03-29 00:00:02', 'John'),
(1010883527, '2016-03-29 00:00:04', 'John'),
(1010883578, '2016-03-29 00:00:06', 'John');
SELECT
A.[gid]
,A.[time]
,A.[name]
,LEAD(A.[time]) OVER(PARTITION BY A.[name] ORDER BY A.[gid]) AS NextTime
,ISNULL(DATEDIFF(second, A.[time],
LEAD(A.[time]) OVER(PARTITION BY A.[name] ORDER BY A.[gid])), -1) AS SecondsTillNext
FROM @location A
ORDER BY A.[gid];
结果
+------------+-------------------------+------+-------------------------+-----------------+
| gid | time | name | NextTime | SecondsTillNext |
+------------+-------------------------+------+-------------------------+-----------------+
| 1010883478 | 2016-03-29 00:00:02.000 | John | 2016-03-29 00:00:04.000 | 2 |
| 1010883527 | 2016-03-29 00:00:04.000 | John | 2016-03-29 00:00:06.000 | 2 |
| 1010883578 | 2016-03-29 00:00:06.000 | John | NULL | -1 |
+------------+-------------------------+------+-------------------------+-----------------+
如果 "next" 行不可用,LEAD
将 return NULL
。如果需要,您可以使用 ISNULL()
将其替换为一些非空值。
SELECT A.gid,A.name,A.time,
(
(SELECT MIN(B.time) 从 [location] B WHERE B.time>A.time AND B.name=A.name)
-
A.time
) 作为 timeTilNext
从[位置] A
我有以下查询,目的是显示每条记录到下一条记录的时间
数据:
gid time name
1010883478 29/03/2016 0:00:02 John
1010883527 29/03/2016 0:00:04 John
1010883578 29/03/2016 0:00:06 John
SQL:
SELECT A.[gid]
,A.[time]
,A.[name]
,(B.[time] - A.[time]) as timeTilNext
FROM [location] A CROSS JOIN [location] B
WHERE B.[gid] IN (
SELECT MIN(C.[gid])
FROM [location] C
WHERE C.[gid] > A.[gid] AND C.[name] = A.[name] )
ORDER BY A.[gid]
当前输出:
gid time name timeTilNext
1010883478 2016-03-29 00:00:02.000 John 1900-01-01 00:00:02.000
1010883527 2016-03-29 00:00:04.000 John 1900-01-01 00:00:02.000
预期输出:
gid time name timeTilNext
1010883478 2016-03-29 00:00:02.000 John 1900-01-01 00:00:02.000
1010883527 2016-03-29 00:00:04.000 John 1900-01-01 00:00:02.000
1010883578 2016-03-29 00:00:06.000 John -1 (or whatever)
但是,它没有显示给定 [name] 的最高 [gid] 的记录(仅第二高)。
我希望最高 [gid] 的 timeTilNext 显示 -1,表示没有更多事件。
关于如何修改我的查询有什么想法吗?
select
*,-1 as 'time until next ' from location t1
where time=(select max(time) from location t2 where t1.name=t2.name) b
在 SQL Server 2012 中,您可以使用 LEAD
window 函数获取 "next" 行的值。
DECLARE @location TABLE ([gid] int, [time] datetime, [name] varchar(50));
INSERT INTO @location ([gid], [time], [name]) VALUES
(1010883478, '2016-03-29 00:00:02', 'John'),
(1010883527, '2016-03-29 00:00:04', 'John'),
(1010883578, '2016-03-29 00:00:06', 'John');
SELECT
A.[gid]
,A.[time]
,A.[name]
,LEAD(A.[time]) OVER(PARTITION BY A.[name] ORDER BY A.[gid]) AS NextTime
,ISNULL(DATEDIFF(second, A.[time],
LEAD(A.[time]) OVER(PARTITION BY A.[name] ORDER BY A.[gid])), -1) AS SecondsTillNext
FROM @location A
ORDER BY A.[gid];
结果
+------------+-------------------------+------+-------------------------+-----------------+
| gid | time | name | NextTime | SecondsTillNext |
+------------+-------------------------+------+-------------------------+-----------------+
| 1010883478 | 2016-03-29 00:00:02.000 | John | 2016-03-29 00:00:04.000 | 2 |
| 1010883527 | 2016-03-29 00:00:04.000 | John | 2016-03-29 00:00:06.000 | 2 |
| 1010883578 | 2016-03-29 00:00:06.000 | John | NULL | -1 |
+------------+-------------------------+------+-------------------------+-----------------+
如果 "next" 行不可用,LEAD
将 return NULL
。如果需要,您可以使用 ISNULL()
将其替换为一些非空值。
SELECT A.gid,A.name,A.time, ( (SELECT MIN(B.time) 从 [location] B WHERE B.time>A.time AND B.name=A.name) - A.time ) 作为 timeTilNext
从[位置] A