Sql 将超前(或滞后)与连接一起使用
明细表需要从标题表获取列数据,包括来自上一个和下一个标题记录的数据 我尝试过使用SELECT、JOIN等多种组合 我太不好意思给你看;) 预期结果(使用明细表) 其目的是,对于给定的细节记录,我可以确定上一个和下一个标题记录的时间戳和位置Sql 将超前(或滞后)与连接一起使用,sql,sql-server,Sql,Sql Server,明细表需要从标题表获取列数据,包括来自上一个和下一个标题记录的数据 我尝试过使用SELECT、JOIN等多种组合 我太不好意思给你看;) 预期结果(使用明细表) 其目的是,对于给定的细节记录,我可以确定上一个和下一个标题记录的时间戳和位置 我的想法是使用HEADERPK连接表,但我不清楚如何针对每个细节对标题记录进行排序。您需要一个窗口函数和一个子查询。我认为最具可读性的方法是将CTE与所有窗口功能一起使用: WITH adjacent_headers AS (
我的想法是使用HEADERPK连接表,但我不清楚如何针对每个细节对标题记录进行排序。您需要一个窗口函数和一个子查询。我认为最具可读性的方法是将CTE与所有窗口功能一起使用:
WITH
adjacent_headers AS
(
SELECT
headerpk,
prev_headerpk = LAG(headerpk) OVER (ORDER BY headerpk),
prev_ts = LAG([timestamp]) OVER (ORDER BY headerpk),
prev_loc = LAG(location) OVER (ORDER BY headerpk),
next_headerpk = LEAD(headerpk) OVER (ORDER BY headerpk),
next_ts = LEAD([timestamp]) OVER (ORDER BY headerpk),
next_loc = LEAD(location) OVER (ORDER BY headerpk)
FROM header
)
SELECT
detail.detailpk,
adjacent_headers.prev_loc,
adjacent_headers.prev_ts,
adjacent_headers.next_loc,
adjacent_headers.next_ts
FROM detail
INNER JOIN adjacent_headers ON
adjacent_headers.headerpk = detail.headerpk
请注意,这假定您正在通过对标题ID列进行排序来定义“上一个”和“下一个”标题记录。如果您只想在相关标题同时包含上一条记录和下一条记录的地方包含详细信息,您可以将其添加到最终查询的
where
子句中。如果您想在join
中使用lead
或lag
,则不能这样做。但是,如果您只想在同一个sql语句中使用它们,可以执行以下操作:
select d.detailpk,
prev_location = lead(h.location) over(order by h.timestamp desc),
prev_timestamp = lead(h.timestamp) over(order by h.timestamp desc),
next_location = lag(h.location) over(order by h.timestamp desc),
next_timestamp = lag(h.timestamp) over(order by h.timestamp desc)
from detail d
join header h on d.headerpk = h.headerpk
order by h.timestamp;
现在,如果您的真实场景中有许多字段需要抓住lead
和lag
项,您可以避免像这样的over
语句:
with
offset as (
select *,
prev_headerPk = lead(headerpk) over(order by timestamp),
next_headerPk = lag(headerpk) over(order by timestamp)
from header
)
select d.detailpk,
prev_location = p.location,
prev_timestamp = p.timestamp,
next_location = n.location,
next_timestamp = n.timestamp
from detail d
left join offset p on d.headerpk = p.prev_headerPk
left join offset n on d.headerpk = n.next_headerPk
你是如何定义“下一步”的?好吧,该死的,我无意中遗漏了问题的一部分。对于所有响应者,在我更新之前,无需提供任何答案。感谢所有这么快回答的人。
select d.detailpk,
prev_location = lead(h.location) over(order by h.timestamp desc),
prev_timestamp = lead(h.timestamp) over(order by h.timestamp desc),
next_location = lag(h.location) over(order by h.timestamp desc),
next_timestamp = lag(h.timestamp) over(order by h.timestamp desc)
from detail d
join header h on d.headerpk = h.headerpk
order by h.timestamp;
with
offset as (
select *,
prev_headerPk = lead(headerpk) over(order by timestamp),
next_headerPk = lag(headerpk) over(order by timestamp)
from header
)
select d.detailpk,
prev_location = p.location,
prev_timestamp = p.timestamp,
next_location = n.location,
next_timestamp = n.timestamp
from detail d
left join offset p on d.headerpk = p.prev_headerPk
left join offset n on d.headerpk = n.next_headerPk