Sql查询集合中的第一行、下一行和最后一行
我有两个表,我试图连接在一起多次。父表称为作业,子表称为路由。一个作业可以有一个或多个路由。我需要我的输出为每个作业包含一条记录,并与Routings表的三个独立联接联接。一个联接用于当前数据(序列中的第一个空日期值),一个联接用于下一个(紧跟在当前之后的序列),最后一个联接用于最后一个(定义为作业的最高序列号) 下面是我收集的一个小样本,用于提供样本数据和所需的输出。它将问题简化为一种更简单的形式,只显示路线,而不显示作业表。如果我能找到一种更容易提取当前值、下一个值和最后一个值的方法,我就可以从那里得到它 我曾尝试通过许多联接进行此查询,但当不存在下一个路由时,它似乎忽略了结果(我需要空值)。执行左外部联接无法解决此问题。我不确定这是因为它是SQL Server 2000还是什么Sql查询集合中的第一行、下一行和最后一行,sql,sql-server,tsql,sql-server-2000,Sql,Sql Server,Tsql,Sql Server 2000,我有两个表,我试图连接在一起多次。父表称为作业,子表称为路由。一个作业可以有一个或多个路由。我需要我的输出为每个作业包含一条记录,并与Routings表的三个独立联接联接。一个联接用于当前数据(序列中的第一个空日期值),一个联接用于下一个(紧跟在当前之后的序列),最后一个联接用于最后一个(定义为作业的最高序列号) 下面是我收集的一个小样本,用于提供样本数据和所需的输出。它将问题简化为一种更简单的形式,只显示路线,而不显示作业表。如果我能找到一种更容易提取当前值、下一个值和最后一个值的方法,我就可
drop table #routing
create table #routing
(
routingId int not null primary key,
jobid int not null,
sequence int not null,
sentdate datetime
)
insert into #routing
select
1, 1, 1, '1/1/2009'
union
select
2, 1, 2, '1/2/2009'
union
select
3, 1, 3, '1/3/2009'
union
select
4, 1, 4, null
union
select
5, 1, 5, null
union
select
6, 2, 1, '1/1/2009'
union
select
7, 2, 2, '1/2/2009'
union
select
8, 2, 3, '1/3/2009'
select * from #routing
/*
Expected Result:
Two Records, one for each job
JobId, CurrentRoutingId, NextRoutingId, LastRoutingId
1 4 5 5
2 null null 8
*/
将这些值作为列存储在jobs表中难道没有意义吗?然后在(我想)您的工作流程需要时更新它们?然后,您可以在上一步执行两个内部联接作业->路由,在下一步执行作业->路由。这里有一个解决方案
select r.jobid, min(rn.routingid) as nextroutingid, max(rl.routingid) as lastroutingid,
max(rn.routingid) as currentroutingid
from routing r
left join routing rn on (rn.jobid = r.jobid) and (rn.sentdate is null)
left join routing rl on (rl.jobid = r.jobid)
group by r.jobid
我曾尝试通过许多联接进行此查询,但当不存在下一个路由时,它似乎忽略了结果(我需要空值)。执行左外部联接无法解决此问题
确保在JOIN子句中针对外部联接表而不是WHERE子句放置任何筛选器。例如:
select curr.jobid, curr.routingid, prev.routingid as prev_routingid
from #routing curr
left join #routing prev
on curr.jobid = prev.jobid
and curr.sequence = prev.sequence+1
而不是:
select curr.jobid, curr.routingid, prev.routingid as prev_routingid
from #routing curr
left join #routing prev
on curr.jobid = prev.jobid
where curr.sequence = prev.sequence+1
第二个版本相当于一个内部连接。这可能会使工作更轻松,但我一直在尽可能避免存储冗余数据。我觉得这是多余的,因为我知道可以通过适当的Transact-SQL检索值。@Justin:在这种情况下,冗余数据更可取。当然,您可以编写sql,但是所涉及的查询比简单的选择要复杂一些。特别是如果这是经常运行。在这种情况下,我主张性能胜过重复存储。如果表中有3列[上一步、当前步、下一步],并且它们都是路由表的外键,我认为这不会是多余的。您没有存储冗余数据,它实际上是第三个标准化设计。此外,根据你给我们的表格,你已经在这样做了。我只是在提倡一种不同的观点…测试?给出了完全不同的结果。误读了他的样本数据中的一列。修正。第二行,你的意思是LastRoutingId=3吗?+1你能提供一个临时表脚本真是太好了。我知道它必须简单一些!谢谢你阅读我的解释,并提出了一个很好的建议。这解决了我的问题。