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

发布于 2024-08-08 16:14:16 字数 1065 浏览 3 评论 0原文

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

下面是我整理的一个小示例,用于提供示例数据和所需的输出。它将问题转化为更简单的形式,实际上只显示路由,而不显示作业表。如果我能找到一种方法来更轻松地提取当前值、下一个值和最后一个值,我就可以从那里获取。

我已通过许多联接尝试此查询,但当不存在下一个路由时(我需要空值),它似乎会忽略结果。执行左外连接并不能解决这个问题。我不确定这是因为它是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

*/

I have two tables that I am trying to join together multiple times. The Parent table is called Jobs, and the child table is called Routings. A Job can have 1 or more Routings. I need my output to contain one record for each job, joined with three separate joins to the Routings table. One join is for Current data (the first null date value in the sequence), one for next (the sequence coming immediately after the current) and the final for the last (defined as the highest sequential number for the job).

Below is a small sample I have put together to provide sample data and the desired output. It takes the problem to a simpler form, showing really only the Routings and not the Job table. If I can find a way to more easily extract the current, next and last values, I can take it from there.

I have attempted this query through many joins, but it seems to be omitting results when no next routing exists (I need null values). Performing a Left Outer Join didn't remedy this. I'm not sure if this is because it's SQL Server 2000 or what.

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

*/

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

柠栀 2024-08-15 16:14:16

我已通过许多联接尝试此查询,但当不存在下一个路由时(我需要空值),它似乎会忽略结果。执行左外连接并不能解决这个问题。

确保在 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

第二个版本相当于内连接。

I have attempted this query through many joins, but it seems to be omitting results when no next routing exists (I need null values). Performing a Left Outer Join didn't remedy this.

Make sure you put any filters against the outer joined tables in the JOIN clause, not the WHERE clause. eg:

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

Rather than:

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

The second version is equivalent to an inner join.

月寒剑心 2024-08-15 16:14:16

将这些值作为列存储在作业表中不是很有意义吗?然后在(我假设)您的工作流程需要时更新它们?然后,您可以在上一步中执行 2 个内部联接 Jobs->Routes,在下一步中执行 Jobs->Routes。

Wouldn't it make sense, to store those values as columns in your jobs table? Then just update them when (I assume) your workflow calls for it? Then you could just do 2 inner joins Jobs->Routes on previous step and Jobs->Routes on next step.

紅太極 2024-08-15 16:14:16

这是一种解决方案

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

Here's one solution

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文