Sql 如果值为-1,则返回上一条记录中的值
我有一个包含LocationId字段的表。在某些情况下,如果记录共享相同的外键,LocationId可能会作为-1出现 我想做的是在我的select查询中,在发生这种情况时,是前面的位置 示例数据:Sql 如果值为-1,则返回上一条记录中的值,sql,sql-server,tsql,sql-server-2008,null,Sql,Sql Server,Tsql,Sql Server 2008,Null,我有一个包含LocationId字段的表。在某些情况下,如果记录共享相同的外键,LocationId可能会作为-1出现 我想做的是在我的select查询中,在发生这种情况时,是前面的位置 示例数据: Record FK StartTime EndTime Location 1 110 2011/01/01 12.30 2011/01/01 6.10 456 2 110 2011/01/01
Record FK StartTime EndTime Location
1 110 2011/01/01 12.30 2011/01/01 6.10 456
2 110 2011/01/01 3.40 2011/01/01 4.00 -1
3 110 2011/01/02 1.00 2011/01/02 8.00 891
4 110 2011/01/02 5.00 2011/01/02 6.00 -1
5 110 2011/01/02 6.10 2011/01/02 6.30 -1
对于记录2,-1应该是456,对于记录4和记录5,-1应该是891,对于整个结果集
with tmp(Record ,FK ,StartTime ,EndTime ,Location)
as( select
1, 110 ,'2011/01/01 12:30', '2011/01/01 6:10', 456 union all select
2, 110 ,'2011/01/01 3:40', '2011/01/01 4:00', -1 union all select
3, 110 ,'2011/01/02 1:00', '2011/01/02 8:00', 891 union all select
4, 110 ,'2011/01/02 5:00', '2011/01/02 6:00', -1 union all select
5, 110 ,'2011/01/02 6:10', '2011/01/02 6:30', -1
)
-- ignore above this line
select curr.Record, curr.FK, curr.StartTime, curr.EndTime,
case when curr.Location=-1 then prev.Location else curr.Location end Location
from tmp curr
outer apply
(select top 1 prev.location
from tmp prev
where curr.location=-1 and prev.FK=curr.FK
and prev.starttime < curr.starttime
and prev.location <> -1
order by prev.starttime desc) prev
对于整个结果集
with tmp(Record ,FK ,StartTime ,EndTime ,Location)
as( select
1, 110 ,'2011/01/01 12:30', '2011/01/01 6:10', 456 union all select
2, 110 ,'2011/01/01 3:40', '2011/01/01 4:00', -1 union all select
3, 110 ,'2011/01/02 1:00', '2011/01/02 8:00', 891 union all select
4, 110 ,'2011/01/02 5:00', '2011/01/02 6:00', -1 union all select
5, 110 ,'2011/01/02 6:10', '2011/01/02 6:30', -1
)
-- ignore above this line
select curr.Record, curr.FK, curr.StartTime, curr.EndTime,
case when curr.Location=-1 then prev.Location else curr.Location end Location
from tmp curr
outer apply
(select top 1 prev.location
from tmp prev
where curr.location=-1 and prev.FK=curr.FK
and prev.starttime < curr.starttime
and prev.location <> -1
order by prev.starttime desc) prev
可以使用相关子查询。例如:
SELECT *
, (SELECT TOP 1 Location
FROM MyTable T2
WHERE T2.Record <= T1.Record
AND T2.FK = T1.FK
AND T2.Location <> -1
ORDER BY T2.Record DESC) AS BestLocation
FROM MyTable T1
可以使用相关子查询。例如:
SELECT *
, (SELECT TOP 1 Location
FROM MyTable T2
WHERE T2.Record <= T1.Record
AND T2.FK = T1.FK
AND T2.Location <> -1
ORDER BY T2.Record DESC) AS BestLocation
FROM MyTable T1
不,你太离题了。。该表有超过800k条记录。。所以它需要健壮,并且不需要where语句中的FK值。@Matt我选择了starttime。如果你需要重新制作一个符咒的顺序,你可以交换记录。。谢谢你,RichardNo,你太离谱了。。该表有超过800k条记录。。所以它需要健壮,并且不需要where语句中的FK值。@Matt我选择了starttime。如果你需要重新制作一个符咒的顺序,你可以交换记录。。谢谢Richard,你能在子查询中使用ORDER BY吗?是的,当使用TOP N时,你可以在子查询中使用ORDER BY。但是,正如mattd所指出的,使用MAX而不是ORDER BY会更快。@ThomasMcLeod我是指你在回答中使用MAX的方式。排序方式意味着需要对结果进行排序,但使用MAX避免了排序,而代价是另一次表扫描。根据表的大小和可用的索引,表扫描可能会更快。您能在子查询中使用ORDER BY吗?是的,当使用TOP N时,您可以在子查询中使用ORDER BY。但是,正如mattd所指出的,使用MAX而不是ORDER BY会更快。@Thomasmclod我指的是您在回答中使用MAX的方式。排序方式意味着需要对结果进行排序,但使用MAX避免了排序,而代价是另一次表扫描。根据表的大小和可用索引,表扫描可能会更快。