加入表格并显示具有最接近即将到来日期的行

时间:2018-08-03 18:13:36

标签: 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  |


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'

谢谢大家!

4 个答案:

答案 0 :(得分:4)

您可以使用apply

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;

答案 1 :(得分:2)

这是使用APPLY的替代方法(这可能是更好的方法)。在使用OUTER APPLY将其查询计划与答案进行比较之后,我不得不说这是次等方法。使用窗口函数可能有一些充分的理由-也许是更复杂的情况。

这使用窗口函数通过排序标准(在此情况下为日期)获取行号。结果将添加到仅返回第一行(日期最早的那一行)的场所列表中。如果两个事件具有相同的地点和日期,则只有一个事件的行号为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

答案 2 :(得分:1)

您将使用apply

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;

如果要包括没有即将发生的事件的场所,则可以使用OUTER APPLY而不是CROSS APPLY

答案 3 :(得分:1)

这是一个老式的解决方案,无需使用<div class="header"> <div> One </div> <div> Two </div> </div> <div class="main"> <div class="sidebar"> Menu </div> <div class="content"> Content </div> </div>

cross apply

它改为使用两个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 并依赖于在同一地点同一天不会发生两个事件的条件...

在此处查看演示:http://rextester.com/RDAPR97793