sql - 使用 Postgres 进行“多个”搜索
问题描述
基本上,我试图从一个表中获取一个值,然后在其他 3 个表中搜索该值。但我想在一个查询中完成这一切。
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 仍然有效吗?
解决方案
CTE -公共表表达式(AFAIK 始终在 Postgres 中具体化)将用作您的第一个查询的占位符,然后您可以使用它来加入其他表。此外,aUNION
听起来像您想要的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
,那么这将返回每个匹配的表一行(除非它被不同的删除,如上所述) - 如果表 1、2 或 3 中的任何一个都没有匹配项,则查询将不返回任何内容。如果您希望从不
users
考虑匹配 (with nulls for unmatched columns
) 的情况下返回单行,则需要LEFT JOIN
用户和至少一个表 t1..t3 之间的 a
编辑 - 回复:确保users
一行始终返回至少一条记录/指示匹配哪些表
如上所述,您可以使用 aLEFT 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,希望能把事情弄清楚?
推荐阅读
- javascript - 为什么我的 Steinhaus-Johnson-Trotter 算法实现会产生重复排列?
- mysql - 如何避免 SELECT 查询中的类型锁定
- docker - 拉取镜像或运行容器时 Docker 挂起
- c - 即使在 if 语句中声明了 break,我如何退出 do-while 循环?
- python - WinError 2 找不到文件:'c:\\python39\\Scripts\\sacremoses.exe' -> 'c:\\python39\\Scripts\\sacremoses.exe.deleteme'
- elasticsearch - Filebeat 如何摄取 .xml 文件?
- laravel-5 - 作曲家更新后出现问题
- r - 仅对 R 中的分类变量进行分类
- python - 我可以创建一个将一些数字添加到任何类实例变量的类方法吗?
- flutter - 查询 FloatingSearchBar