在不使用SQL Windows函数,CLR或CTE的情况下,我该怎么做?
考虑此数据集:
Dispatch_Id (PK) | Job_Id | Tech | Scheduled_Time
1 | 1 | Brad | 08:35
2 | 1 | John | 05:29
3 | 2 | Steve | 13:02
4 | 3 | Brad | 10:15
5 | 3 | Kevin | 10:15
6 | 4 | Kevin | 12:00
这就是我要结束的:
Dispatch_Id (PK) | Job_Id | Tech | Scheduled_Time
2 | 1 | John | 05:29
3 | 2 | Steve | 13:02
4 | 3 | Brad | 10:15
6 | 4 | Kevin | 12:00
这是我已经开始的代码,但问题是它没有获得MIN(Scheduled_Time)的MIN(Dispatch_Id)。我需要他们一起努力。
SELECT Job.Name
,NextAppt.Next_Appointment
,Tech.Tech_Name
FROM Job
LEFT JOIN (SELECT Job_Id, MIN(Schedule_Time) AS Next_Appointment, MIN(Dispatch_Id) AS Dispatch_Id
FROM Dispatch
GROUP BY Job_Id) NextAppt ON Job.Job_Id = NextAppt.Job_Id
LEFT JOIN Dispatch ON NextAppt.Dispatch_Id = Dispatch.Dispatch_Id
LEFT JOIN Tech ON Dispatch.Tech_Id = Tech.Tech_Id
感谢您的帮助。
编辑:
这是我过去所做的事情,但它使我头疼,并且在进行大型查询时很慢。加上这会对调度ID进行字母数字排序。因此,当有两个相同的日期时,就不那么精确了。
SELECT Job.Name
,CAST(SUBSTRING(NextAppt.Next_Appointment,1,22) AS DATETIME) AS 'Next_Appointment'
,Tech.Tech_Name
FROM Job
LEFT JOIN (SELECT Job_Id, MIN(CONVERT(NVARCHAR(25),Schedule_Time,126)+'-'+CAST(Dispatch_Id AS NVARCHAR)) AS Next_Appointment
FROM Dispatch
GROUP BY Job_Id) NextAppt ON Job.Job_Id = NextAppt.Job_Id
LEFT JOIN Dispatch ON CAST(SUBSTRING(NextAppt.Next_Appointment,21,99) AS INT) = Dispatch.Dispatch_Id
LEFT JOIN Tech ON Dispatch.Tech_Id = Tech.Tech_Id
答案 0 :(得分:1)
您处于正确的轨道,但是您的派生表需要使用TOP 1和ORDER BY而不是MIN。它还需要在Job_Id
上进行关联,但要在PK上进行加入。
示例(我知道我之前已经发布了此内容,但我找不到它很容易):
伪代码,因为您仅发布了查询结果而未发布DDL:
SELECT...
FROM SomeTables t1
INNER JOIN Dispatch t2 ON t2.PK=(
SELECT TOP 1 PK
FROM Dispatch t3
WHERE t1.Job_id=t3.Job_id
ORDER BY Schedule_Time, Dispatch_Id ASC
)
结果t2
将具有Job_Id
中每个t1
的第一个调度行。
答案 1 :(得分:1)
这是我一直在寻找的方法。假设您要加入PK索引,它会进行非常优化。
SELECT Job.Name
,NextAppt.Next_Appointment
,Tech.Tech_Name
FROM Job
OUTER APPLY (SELECT TOP 1 Job_Id, Dispatch_Id, Tech_Id, Schedule_Time AS 'Next_Appointment'
FROM OE_Job_Dispatch
WHERE Job_Id = Job.Job_Id
ORDER BY Scheduled_Time) NextAppt
LEFT JOIN Tech ON NextAppt.Tech_Id = Tech.Tech_Id
此方法似乎在LEFT JOIN方法中使用了“表查找”与较慢的“表扫描”。这是OUTER APPLY方法:
这是LEFT JOIN方法:
这是我以前的串联JOIN方法: 请记住,如果数据不正确,这可能是不可预测的。在这种情况下,它执行得很好,但是可能不可靠。
答案 2 :(得分:0)
您可以将ROW_NUMBER()
与TIES
子句一起使用:
SELECT TOP (1) WITH TIES d.*
FROM dataset d
ORDER BY ROW_NUMBER() OVER (PARTITION BY Job_Id ORDER BY Scheduled_Time, Dispatch_Id);