我有以下SQL查询:
SELECT "users".* FROM "users"
WHERE (
users.id IN (SELECT manager_id FROM managerships WHERE managerships.employee_id = 1234) OR
users.custom_id IN (SELECT manager_custom_id FROM managerships WHERE managerships.employee_id = 1234) OR
users.saml_id IN (SELECT manager_saml_id FROM managerships WHERE managerships.employee_id = 1234) OR
users.email IN (SELECT manager_email FROM managerships WHERE managerships.employee_id = 1234)
)
现在我相信应该有一种方法可以从我的managerships
表中选择一次并重复使用它,例如:
SELECT manager_id, manager_email, manager_custom_id, manager_saml_id FROM managerships WHERE managerships.employee_id = 1234
我怎样才能实现这一目标?谢谢!
答案 0 :(得分:3)
您可以使用WITH将聚合带入CTE(公用表表达式):
WITH m AS (SELECT manager_id
,manager_email
,manager_custom_id
,manager_saml_id
FROM managerships
WHERE managerships.employee_id = 1234
)
SELECT "users".* FROM "users"
WHERE (
users.id IN (SELECT manager_id FROM m) OR
users.custom_id IN (SELECT manager_custom_id FROM m) OR
users.saml_id IN (SELECT manager_saml_id FROM m) OR
users.email IN (SELECT manager_email FROM m)
);
请参阅https://www.postgresql.org/docs/9.1/static/queries-with.html
答案 1 :(得分:2)
您可以尝试一起加入users
和managerships
表:
SELECT t1.*
FROM "users" t1
INNER JOIN managerships t2
ON t1.id = t2.manager_id OR
t1.custom_id = t2.manager_custom_id OR
t1.saml_id = t2.manager_saml_id OR
t1.email = t2.manager_email
WHERE t2.employee_id = 1234;
这种方法除了易于阅读之外,还具有可以在两个表上使用索引的优点,假设您已经定义了它们。
答案 2 :(得分:1)
您可以像这样编写查询:
SELECT u.*
FROM users u CROSS JOIN
managerships m
WHERE m.employee_id = 1234 AND
(u.id = m.manager_id OR
u.custom_id = m.manager_custom_id OR
u.saml_id = m.manager_saml_id OR
u.email = m.manager_email
);
我认为性能没有任何改善。此查询的任何版本都需要managerships(employee_id)
上的索引。使用此索引,您的查询和这应该具有几乎相同的性能。
注意:您可以使用on
来表达这一点 - 它也会做同样的事情。由于OR
条件无法真正优化,这就是我将它们放入WHERE
子句的原因。