当条件不为第二张表产生结果时,如何在LEFT JOIN上返回NULL

时间:2018-10-28 06:02:41

标签: mysql sql join

我有一个表Account,它具有零对多的Subscription,并且我想返回Account.nameSubscription.end

如果没有有效的订阅,则Subscription.end应该是NULL

这是我的(不正确的)SQL:

SELECT acc.name,
       s.t_end
FROM ACCOUNT acc LEFT JOIN SUBSCRIPTION s ON acc.id = s.account_id
WHERE acc.id = 1
  AND s.t_start <= CURRENT_TIMESTAMP()
  AND s.t_end > CURRENT_TIMESTAMP()

我的SQL问题:如果该帐户没有匹配的订阅,它将返回空集:

acc.name | s.t_end
------------------
<nothing>

我想要什么:

acc.name | s.t_end
------------------
1        | NULL

2 个答案:

答案 0 :(得分:4)

每当使用Left Join时,右侧表上是否存在任何Where条件;它将限制数据,并且您将无法根据需要从最左边的表中获取所有行。

相反,您可以将右侧表上的Where条件转换为联接ON条件:

SELECT acc.name,
       s.t_end
FROM ACCOUNT acc 
LEFT JOIN SUBSCRIPTION s ON acc.id = s.account_id AND 
                            s.t_start <= CURRENT_TIMESTAMP() AND 
                            s.t_end > CURRENT_TIMESTAMP()
WHERE acc.id = 1

此外,将尽可能多的条件放入JOIN ON条件中通常是一种良好做法,因为它可以提高查询的可读性。如果更改了Join类型,更改这些查询也将更加容易。

答案 1 :(得分:0)

您要在订阅表上应用where条件,因此由于where条件,左联接的行为类似于内部联接。

尝试消除where条件,如果不能,则可以使用以下查询-

SELECT acc.name,
       s.t_end
FROM ACCOUNT acc 
LEFT JOIN 
(select account_id,t_end from SUBSCRIPTION 
where 
     t_start <= CURRENT_TIMESTAMP()
and  t_end > CURRENT_TIMESTAMP()
) s
ON acc.id = s.account_id
WHERE acc.id = 1