我想像这样做一个正确的联接:
我希望所有B都没有任何A. 要么 所有B 只是 A.type<> 0(如果他们有一个A.type = 0我不想要他们)
现在我有了这个:
SELECT B.*
FROM A
RIGHT JOIN B ON A.ticket = B.id
WHERE A.id IS NULL
AND B.state NOT IN (3,4,10)
AND B.disable = 0
答案 0 :(得分:2)
没有理由使用RIGHT JOIN
。对于大多数人来说,由于两个原因,它比LEFT JOIN
更令人困惑。首先,读取FROM
子句"从左到右"。 LEFT JOIN
保留子句中第一个表中的所有行。尚未见过的最后一张表中的RIGHT JOIN
。其次,FROM
子句从左到右解析,这在组合多个外连接时引入了一些微妙的问题。
接下来,您明确说:
我想排除没有A.Type = 0
的B.
这相当于:
我想要包含没有A.Type = 0的B
这不是一个外部联接。我认为这更接近你想要的东西:
在你的情况下:
SELECT B.*
FROM B
WHERE NOT EXISTS (SELECT 1
FROM A
WHERE A.ticket = B.id AND A.Type = 0
) AND
B.state NOT IN (3, 4, 10) AND B.disable = 0;
答案 1 :(得分:0)
你想要B,如果A中有任何值,那么它的类型是<> 0,所以:
SELECT * FROM B
WHERE B.id NOT IN (
SELECT ticket FORM A
WHERE A.type = 0 )
不可接受
可能你想要这样的东西:
SELECT B.* FROM A
RIGHT JOIN B
ON A.ticket = B.id
WHERE
A.type<>0
-- (A.id is null OR A.type<>0)
-- A.id IS NULL
-- AND A.type <> 0 -- added for exclude a.type = 0
AND B.state NOT IN (3,4,10)
AND B.disable = 0
这意味着 JOIN
A.type
不在0
的位置以及您为查询计划的其他条件
答案 2 :(得分:0)
您可以通过这种方式使用连接而不是子查询获得所需的结果:
select B.id
from A right join B on A.ticket = B.id
where B.state not in (3, 4, 10) and B.disable = 0
group by B.id
having count(case when A.ticket is not null and A.type = 0 then 1 end) = 0;
通过这种方式,您只考虑B中没有任何匹配行的B行或者有A.type = 0
但没有匹配的行。
错误的预编辑答案
我会选择:
select B.*
from A right join B on A.ticket = B.id
where B.state not in (3, 4, 10) and B.disable = 0 and coalesce(A.type, 1) <> 0
这样您只会考虑不加入或加入但没有A.type = 0
的行。
请注意,根据您使用的数据库,coalesce
函数可能必须替换为等效的函数。
答案 3 :(得分:0)
使用子查询来实现相同的查询并保持RIGHT JOIN。此方法也可能更快,因为它尝试从两个JOIN端的表中连接最少量的记录。
SELECT B2.*
FROM
(SELECT ticket, type FROM A WHERE type=0) A2
RIGHT JOIN
(SELECT * FROM B WHERE B.state NOT IN (3,4,10) AND B.disable = 0) B2
ON A2.ticket = B2.id WHERE A2.ticket IS NULL;