Sql 联接表并显示具有最近即将到来日期的行
如何连续显示最近的即将举行的活动 假设我有两张桌子:Sql 联接表并显示具有最近即将到来日期的行,sql,sql-server,Sql,Sql Server,如何连续显示最近的即将举行的活动 假设我有两张桌子: EVENTS |id |venueID |eventName |date | |---|-----------|------------|------------| |10 |1 |Volleyball |2018-08-01 | |11 |1 |Concert |2018-08-05 | |12 |1 |Faire |2018-08-07
EVENTS
|id |venueID |eventName |date |
|---|-----------|------------|------------|
|10 |1 |Volleyball |2018-08-01 |
|11 |1 |Concert |2018-08-05 |
|12 |1 |Faire |2018-08-07 |
VENUES
|id |Name |
|---|-----------|
|1 |Place1 |
|2 |Place2 |
由于今天是8月3日,即将举行的活动将是“音乐会”,桌子如下所示:
|Venue |Event |Date |
|---------|--------|-----------|
|Place1 |Concert |2018-08-05 |
我当前的代码有一个问题,即如果有多个即将发生的事件,则整行的重复次数与事件的重复次数相同
我希望每一排的场地只显示一次,只有最近的即将举行的活动
此外,即使没有即将举行的活动,我也希望显示与场地的排。相反,它可以说“没有即将到来的事件”
这是我的
SELECT
venues.id,
venues.Name,
events.eventName,
events.date
FROM VENUES
JOIN EVENTS
ON (venues.id = events.venueID)
WHERE events.date >= '$current_date'
谢谢大家 您将使用
应用:
SELECT v.id, v.Name, e.eventName, e.date
FROM VENUES v CROSS APPLY
(SELECT TOP (1) e.*
FROM EVENTS e
WHERE v.id = e.venueID AND e.date >= '$current_date'
) e;
select vid, place,eventName,date
from venues
left join
(select evid nevid, min(date) ndate from events where date>getdate()
group by evid) nxtevents ON nevid=vid
left join events ON evid=vid AND date=ndate
如果您想包括没有即将举行的活动的场馆,您可以使用外部应用
,而不是交叉应用
,您可以使用应用
:
select v.Venue, coalesce(e.Event, 'No Upcoming Events') Event, e.Date
from VENUES v outer apply
( select top (1) e.*
from event e
where e.venueID = v.id and
e.date >= '$current_date'
order by e.date
) e;
这里有一个替代使用APPLY
(这可能是更好的方法)的方法。将此查询计划与使用OUTER APPLY
的答案进行比较后,我不得不说这是一种较差的方法。可能有一些很好的理由使用窗口函数——这可能是一个更复杂的场景
它使用一个窗口函数,通过排序条件(在本例中为日期)获取行号。结果将加入场馆列表,只返回1行(日期最早的一行)。如果两个活动的地点和日期相同,则只有一个活动的行号为1。不能在APPLY中使用窗口函数,因此需要使用内部查询
SELECT v.Name Venue
, COALESCE(eRanked.eventName, 'No Events') Event
, eRanked.Date
FROM Venues v
LEFT JOIN (
SELECT e.VenueId, e.eventName, e.date
, ROW_NUMBER() OVER (PARTITION BY e.VenueId ORDER BY e.Date) rowId
FROM Events e
WHERE e.date > '$curent_date'
) eRanked ON eRanked.VenueId = v.id AND eRanked.RowId = 1
这里有一个很好的老式解决方案,它可以在没有交叉应用的情况下工作:
SELECT v.id, v.Name, e.eventName, e.date
FROM VENUES v CROSS APPLY
(SELECT TOP (1) e.*
FROM EVENTS e
WHERE v.id = e.venueID AND e.date >= '$current_date'
) e;
select vid, place,eventName,date
from venues
left join
(select evid nevid, min(date) ndate from events where date>getdate()
group by evid) nxtevents ON nevid=vid
left join events ON evid=vid AND date=ndate
它使用两个左连接
,并依赖于同一场地内同一天不会有两个活动的条件
请看这里的演示:Hey@Gordon,似乎您忘记在子查询中放置top(1)
。目前,查询将列出给定场馆列表的所有未来活动,请参见此处@cars10m。抢手货