我想与另一个表(tableB)一起过滤表(tableA)。
我用于获取tableA结果的代码
select c.id, a.conversation_id, a.tag, c.email, c.created_at
from conversation c
right join (select * from conversation_tag
where tag = 'atlas-interest') as a
on a.conversation_id = c.id;
tableA
tableB
我想通过“电子邮件”外部连接这两个表。但是,我不断遇到语法问题
我的代码
select * from contact con
LEFT JOIN (select c.id, a.conversation_id, a.tag, c.email, c.created_at
from conversation c
right join (select * from conversation_tag
where tag = 'atlas-interest') as a
on a.conversation_id = c.id)) ON con.email = cc.email
UNION
select * from con
RIGHT JOIN (select c.id, a.conversation_id, a.tag, c.email, c.created_at
from conversation c
right join (select * from conversation_tag
where tag = 'atlas-interest') as a
on a.conversation_id = c.id)) on con.email = cc.email;
我的另一个问题是,嵌套选择中的代码很容易变得混乱。是否有什么方法可以将tableA保存为变量,而仅在加入tableB时调用该变量?
我发现了这种方法SET @v1 := (SELECT COUNT(*) FROM user_rating);
,但似乎一次只能保存一列。
答案 0 :(得分:0)
您为子查询省略了cc
别名。
SELECT * FROM contact con
LEFT JOIN (
SELECT c.id, a.conversation_id, a.tag, c.email, c.created_at
FROM conversation c
RIGHT JOIN (
SELECT * FROM conversation_tag
WHERE tag = 'atlas-interest') AS a
ON a.conversation_id = c.id
) AS cc ON con.email = cc.email
UNION
SELECT c.id, a.conversation_id, a.tag, c.email, c.created_at
FROM conversation c
RIGHT JOIN (
SELECT * FROM conversation_tag
WHERE tag = 'atlas-interest') AS a
ON a.conversation_id = c.id
) AS cc ON con.email = cc.email
为避免重复子查询,您可以定义一个视图:
CREATE VIEW atlas_conversations AS
SELECT c.id, a.conversation_id, a.tag, c.email, c.created_at
FROM conversation c
RIGHT JOIN (
SELECT * FROM conversation_tag
WHERE tag = 'atlas-interest'
) AS a ON a.conversation_id = c.id;
那么您可以做:
SELECT *
FROM contact AS con
LEFT JOIN atlas_conversations AS cc ON con.email = cc.email
UNION
SELECT *
FROM contact AS con
RIGHT JOIN atlas_conversations AS cc ON con.email = cc.email
答案 1 :(得分:0)
这不是答案,但是评论太久。关于您的第一个查询...
select c.id, a.conversation_id, a.tag, c.email, c.created_at
from conversation c
right join (select * from conversation_tag
where tag = 'atlas-interest') as a
on a.conversation_id = c.id;
我们通常不使用RIGHT OUTER JOIN
,因为它们比左外部联接更难读。毕竟,您选择conversation_tag
行和tag = 'atlas-interest'
行,然后将它们的conversation
行加入外部。但是,为什么还要外部联接呢?没有相关的conversation_tag
怎么可能有conversation
?那将意味着数据库损坏(由于缺少外键)。
这就是说,您的查询应该只是:
select *
from conversation_tag ct
join conversation c on c.id = ct.conversation_id
where ct.tag = 'atlas-interest';
答案 2 :(得分:0)
您的第一个查询可以简化为:
select c.id, ct.conversation_id, ct.tag, c.email, c.created_at
from conversation c join
conversation_tag ct
on ct.conversation_id = c.id
where ct.tag = 'atlas-interest';
我怀疑您在conversation_id
中是否有不匹配的conversation_tag
。
接下来,您希望在con
上进行完全外部联接。为此,请收集所有电子邮件并使用left join
:
select ct.*, con.*
from ((select c.email
from con c
) union -- on purpose to remove duplicates
(select c.email
from conversation c join
conversation_tag ct
on ct.conversation_id = c.id
where ct.tag = 'atlas-interest'
)
) e left join
con
on e.email = con.email left join
(select c.id, ct.conversation_id, ct.tag, c.email, c.created_at
from conversation c join
conversation_tag ct
on ct.conversation_id = c.id
where ct.tag = 'atlas-interest'
) ct
on e.email = ct.email;
left join
/ right join
/ union
骇客与真实的full join
并不太相关。例如,它将删除重复项。