我有以下3张桌子:
对于每辆车,我需要可视化有关最近(最近)预订的数据:
如果没有给定汽车的预订,我只需要显示汽车型号。其他字段必须为空。
我写了以下查询:
SELECT
Reservations.CarId,
res.MostRecent,
Reservations.UserId,
Reservations.ReservedOn,
Reservations.ReservedUntil
FROM
Reservations
JOIN (
Select
Reservations.CarId,
MAX(Reservations.ReservedOn) AS 'MostRecent'
FROM
Reservations
GROUP BY
Reservations.CarId
) AS res ON res.carId = Reservations.CarId
AND res.MostRecent = Reservations.ReservedOn
这第一个有效,但是我被困住以获得所需的结果。如何编写完整的查询?
答案 0 :(得分:0)
使用not exists
:
select r.* from reservations r
where not exists (
select 1 from reservations
where carid = r.carid and reservedon > r.reservedon
)
您可以使用上面的代码创建一个CTE
并将其连接到其他表:
with cte as (
select r.* from reservations r
where not exists (
select 1 from reservations
where carid = r.carid and reservedon > r.reservedon
)
)
select c.carid, c.model, u.username, cte.reservedon, cte.reserveduntil
from cars c
left join cte on c.carid = cte.carid
left join users u on u.userid = cte.userid
如果您不想使用CTE:
select c.carid, c.model, u.username, t.reservedon, t.reserveduntil
from cars c
left join (
select r.* from reservations r
where not exists (
select 1 from reservations
where carid = r.carid and reservedon > r.reservedon
)
) t on c.carid = t.carid
left join users u on u.userid = t.userid
答案 1 :(得分:0)
这似乎是经典的每组前n个问题。
一种实现方法是使用OUTER APPLY
。它是一个相关的子查询(横向联接),它为Cars
表中的每一行返回最新的Reservation。如果某辆车不存在这样的预订,则将为空。
如果在Reservations
上为(CarID, ReservedOn DESC)
表创建索引,则此查询应比自联接更有效。
SELECT
Cars.CarID
,Cars.Model
,A.ReservedOn
,A.ReservedUntil
,A.UserName
FROM
Cars
OUTER APPLY
(
SELECT TOP(1)
Reservations.ReservedOn
,Reservations.ReservedUntil
,Users.UserName
FROM
Reservations
INNER JOIN Users ON Users.UserId = Reservations.UserId
WHERE
Reservations.CarID = Cars.CarID
ORDER BY
Reservations.ReservedOn DESC
) AS A
;
有关此常见问题的其他方法,请参见Get top 1 row of each group