Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql查询集合中的第一行、下一行和最后一行_Sql_Sql Server_Tsql_Sql Server 2000 - Fatal编程技术网

Sql查询集合中的第一行、下一行和最后一行

Sql查询集合中的第一行、下一行和最后一行,sql,sql-server,tsql,sql-server-2000,Sql,Sql Server,Tsql,Sql Server 2000,我有两个表,我试图连接在一起多次。父表称为作业,子表称为路由。一个作业可以有一个或多个路由。我需要我的输出为每个作业包含一条记录,并与Routings表的三个独立联接联接。一个联接用于当前数据(序列中的第一个空日期值),一个联接用于下一个(紧跟在当前之后的序列),最后一个联接用于最后一个(定义为作业的最高序列号) 下面是我收集的一个小样本,用于提供样本数据和所需的输出。它将问题简化为一种更简单的形式,只显示路线,而不显示作业表。如果我能找到一种更容易提取当前值、下一个值和最后一个值的方法,我就可

我有两个表,我试图连接在一起多次。父表称为作业,子表称为路由。一个作业可以有一个或多个路由。我需要我的输出为每个作业包含一条记录,并与Routings表的三个独立联接联接。一个联接用于当前数据(序列中的第一个空日期值),一个联接用于下一个(紧跟在当前之后的序列),最后一个联接用于最后一个(定义为作业的最高序列号)

下面是我收集的一个小样本,用于提供样本数据和所需的输出。它将问题简化为一种更简单的形式,只显示路线,而不显示作业表。如果我能找到一种更容易提取当前值、下一个值和最后一个值的方法,我就可以从那里得到它

我曾尝试通过许多联接进行此查询,但当不存在下一个路由时,它似乎忽略了结果(我需要空值)。执行左外部联接无法解决此问题。我不确定这是因为它是SQL Server 2000还是什么

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你能提供一个临时表脚本真是太好了。我知道它必须简单一些!谢谢你阅读我的解释,并提出了一个很好的建议。这解决了我的问题。