我有一个表Account
,它具有零对多的Subscription
,并且我想返回Account.name
和Subscription.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
答案 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