左加入最近的记录,如果存在

时间:2015-07-11 00:06:31

标签: mysql sql join relationship

我有一张人的表,我想提取最新的事件记录,但可能没有。

所以我的问题是,即使我离开加入以确保我为每个人创造了一个记录,但我只会带回那些有事件的人,因为我是将日期的最大值作为标准。

SELECT *
FROM tbl_people
LEFT JOIN tbl_events ON
    tbl_people.People_UID = tbl_events.People_UID
WHERE tbl_people.Active = 1
AND (
    SELECT MAX(Event_Date) FROM tbl_events
    )

将具有以下内容

People_UID

事件将具有以下内容

Event_UID, People_UID, Event_Name, Event_Date

就像我说的那样,我喜欢的是这样的输出:

Jen, Had a Baby, 7/10/2015
Shirley
Susan
Megan, Had a Baby, 8/5/2014
etc.

我希望这是有道理的。

4 个答案:

答案 0 :(得分:1)

这取决于数据库。

如果你正在使用MySQL,你可以简单地将相关子查询放入外连接的on子句中,如下所示:

select *
  from tbl_people p
  left join tbl_events_latest e
    on p.people_uid = e.people_uid
   and e.event_date =
       (select max(x.event_date) from tbl_events x where x.people_uid = e.people_uid)
 where p.active = 1

在其他数据库中,可能不是这样。例如,在Oracle中,您会收到错误消息。您也可以运行:

with tbl_events_latest as
 (select *
    from tbl_events e
   where event_date = ( select max(x.event_date)
                          from tbl_events x
                         where x.people_uid = e.people_uid ) )
select *
  from tbl_people p
  left join tbl_events_latest e
    on p.people_uid = e.people_uid
 where p.active = 1

答案 1 :(得分:0)

执行此操作的一种方法是在联接中使用相关子查询,该子查询检查对于具有较晚日期的同一个人,不存在任何事件:

SELECT *
FROM tbl_people p
LEFT JOIN tbl_events e 
    ON p.People_UID = e.People_UID 
    AND NOT EXISTS (
       SELECT 1 FROM tbl_Events 
       WHERE e.People_UID = People_UID 
         AND Event_Date > e.Event_Date
    )
WHERE p.Active = 1

但它可能不是最有效的解决方案;也许首先限制左连接集更好。 (或者想一想,存在应该更好)。

给出样本数据集,如:

People_UID  Event_UID   People_UID  Event_Name          Event_Date
Jen         1           Jen         Had a Baby          2015-07-10
Jen         3           Jen         Bought a horse      2013-07-10
Shirley     NULL        NULL        NULL                NULL
Susan       NULL        NULL        NULL                NULL
Megan       2           Megan       Had a Baby          2014-08-05
Megan       4           Megan       Had another Baby    2015-08-05

这将是结果:

People_UID  Event_UID   People_UID  Event_Name          Event_Date
Jen         1           Jen         Had a Baby          2015-07-10
Shirley     NULL        NULL        NULL                NULL
Susan       NULL        NULL        NULL                NULL
Megan       4           Megan       Had another Baby    2015-08-05

使用连接可能如下所示:

SELECT *
FROM tbl_people p
LEFT JOIN (
    SELECT e.* 
    FROM tbl_events e 
    JOIN (
       SELECT PEOPLE_UID, MAX(EVENT_DATE) MDATE 
       FROM tbl_Events GROUP BY People_UID
    ) A ON A.MDATE = E.event_date AND e.People_UID = A.People_UID 
) B ON p.People_UID = b.People_UID 
WHERE p.Active = 1

答案 2 :(得分:0)

select * from 
(  SELECT *, row_number() over (partition by tbl_people.name order by tbl_events.Event_Date desc) as rn 
     FROM tbl_people
     LEFT JOIN tbl_events 
       ON tbl_people.People_UID = tbl_events.People_UID
    WHERE tbl_people.Active = 1 ) t 
where t.rn = 1

答案 3 :(得分:0)

如果是Sql Server,您可以使用OUTER APPLY

SELECT *
FROM tbl_people p
OUTER APPLY(SELECT TOP 1 Event_Date 
            FROM tbl_events e
            WHERE p.People_UID = e.People_UID
            ORDER BY Event_Date DESC)oa
WHERE p.Active = 1

或者,如果您想选择日期,那么:

SELECT *
FROM tbl_people p
OUTER APPLY(SELECT MAX(Event_Date) AS Event_Date 
            FROM tbl_events e
            WHERE p.People_UID = e.People_UID)oa
WHERE p.Active = 1