LEFT OUTER JOIN获取max()并包含NULL值

时间:2015-06-20 11:06:52

标签: mysql sql join

我设法通过左外连接获取数据并包含NULL值。这是我目前的查询:

select s.user, a.id, a.datetime as date, a.total_time 
from steam_accounts s 
left outer join activity a on a.steam_id = s.id 
where s.user_id = 1

这会返回:

enter image description here

这几乎是完美的。但现在我需要使用max(a.id)过滤结果,如果没有来自外连接的匹配,则包含空值。

这是我尝试过的:

select s.id, s.user, max(a.id), a.datetime as date, a.total_time
from steam_accounts s
left outer join activity a on a.steam_id = s.id
where s.user_id = "1"

结果:

enter image description here

所有空值都消失了。我只想过滤掉前一个查询中的前两个结果。

这是我想要的结果:

enter image description here

非常感谢。感谢

4 个答案:

答案 0 :(得分:1)

使用X509Certificate

对结果进行的任何聚合都将返回null

答案 1 :(得分:1)

唉,MySQL没有OUTER APPLYLATERAL JOIN,所以效率会低于原来的效率。似乎这样的东西应该产生你想要的东西:

SELECT
    s.id
    ,s.user
    ,ActivityIDs.MaxActivityID
    ,activity.datetime as date
    ,activity.total_time
FROM
    steam_accounts s
    LEFT JOIN
    (
        SELECT
            a.steam_id
            ,max(a.id) AS MaxActivityID
        FROM activity a
        GROUP BY a.steam_id
    ) AS ActivityIDs
    ON ActivityIDs.steam_id = s.id
    LEFT JOIN activity ON
        activity.id = ActivityIDs.MaxActivityID
WHERE
    s.user_id = 1

对于每个steam_account,我们在第一个activity中找到一个LEFT JOIN,其中包含最大ID。然后,我们使用第二个activity中找到的ID来获取剩余的LEFT JOIN个详细信息。

答案 2 :(得分:0)

我能想到的是将ROW_NUMBER()与SQL Server或PostgreSQL中的分区功能一起使用。这里有一个如何在MySQL中执行此操作的示例:

http://blog.sqlauthority.com/2014/03/09/mysql-reset-row-number-for-each-group-partition-by-row-number/

接下来,我会按用户对结果集进行分区,然后按date DESCENDING对其进行排序,然后记录ROW_NUMBER等于1的记录。

我在这里使用SQL Server功能给出了类似的答案:https://stackoverflow.com/a/30952154/3680098

它应该产生如下结果集:

Result set

答案 3 :(得分:0)

使用聚合来计算最大值。然后使用另一个left join加入该记录:

select s.user, a.id, a.datetime as date, a.total_time 
from steam_accounts s left outer join
     activity a
     on a.steam_id = s.id left outer join
     (select a.steam_id, max(a.id) as maxid
      from activity a
      group by a.steam_id
     ) amax
     on amax.steam_id = a.steam_id and amax.maxid = a.id
where s.user_id = 1;