基本上,我试图从一个表中获取一个值,然后在另外三个表中搜索该值。但我想在一个查询中完成所有这些。
select user_id from users where email = 'bob@example.com
该搜索的值需要进入如下查询:
SELECT *
FROM table1
JOIN table2 ON (table1.user_id =
table2.user_id)
WHERE table1.user_id = <<<THE RESULTS FROM THE FIRST QUERY>>>
OR table2.user_id = <<<THE RESULTS FROM THE FIRST QUERY>>>
如果user_id不在第一个表中,那么这个JOIN仍然有用吗?
答案 0 :(得分:1)
CTE - Common Table Expression(AFAIK始终在Postgres中实现)将作为第一个查询的占位符,然后您可以使用它来加入其他表。此外,UNION
听起来像您想要的OR
样式查找一个或多个表t1 .. t3
中的匹配数据,例如:
WITH cteUsers AS
(
select user_id from users where email = 'bob@example.com'
)
SELECT t1.user_id, t1.othercol, ...
FROM table1 t1 INNER JOIN cteUsers cte on t1.user_id = cte.user_id
UNION
SELECT t2.user_id, t2.othercol, ...
FROM table1 t2 INNER JOIN cteUsers cte on t2.user_id = cte.user_id
UNION
SELECT t3.user_id, t3.othercol, ...
FROM table1 t3 INNER JOIN cteUsers cte on t3.user_id = cte.user_id;
附注:
othercol
中t1..t3
列中返回的数字和类型必须匹配。othercol
值的多个表中匹配,则UNION
将具有删除重复项的效果(类似于DISTINCT
)。如果您想要重复的行,请将其替换为UNION ALL
。t1 .. t3
成功将连接匹配到users
,那么每个匹配的表将返回一行(除非它被不同的表删除,如上所述)users
返回单行而不管匹配(with nulls for unmatched columns
),那么用户与至少一个表t1..t3之间需要LEFT JOIN
编辑 - 回复:确保users
行始终返回至少一条记录/表明哪些表匹配
如上所述,您可以使用LEFT OUTER JOIN
来处理3个表中任何一个都没有匹配的情况。在这里,我将3个表匹配的输出汇总到另一个CTE中,然后在CTE之间做一个最终的LOJ,用coalesce
突出显示连接失败的位置(你可以显然也会留下null
,如果需要的话:
WITH cteUsers AS
(
-- Replace with bob to see a match in 2 tables
-- Replace with fred to see a match in 1 table.
select user_id from users where email = 'missing@example.com'
),
cteTables AS
(
SELECT t1.user_id, 'MatchedTable1' as match, t1.othercol
FROM table1 t1 INNER JOIN cteUsers cte on t1.user_id = cte.user_id
UNION
SELECT t2.user_id, 'MatchedTable2' as match, t2.othercol
FROM table2 t2 INNER JOIN cteUsers cte on t2.user_id = cte.user_id
UNION
SELECT t3.user_id, 'MatchedTable3' as match, t3.othercol
FROM table3 t3 INNER JOIN cteUsers cte on t3.user_id = cte.user_id
)
SELECT u.user_id, coalesce(match, 'Not Matched At All') as matched, t.othercol
FROM cteUsers u LEFT OUTER JOIN cteTables t ON u.user_id = t.user_id;
我已经放了一个SqlFiddle up here,希望能够解决问题吗?