我在客户推介表上有一个查询,其中每行包含推荐客户的客户ID和推荐客户。因此,如果Bob with custID 100将带有custID 200的John引用到我们的产品,我们在referrals表中输入一行,其中refer_user_id为100,refer_user_id为200.
给定user_id列表,我想在referenced_user_id列和referenced_user_id列中搜索任何匹配项。我弄清楚如何执行此操作的唯一方法是在两列上执行OR,并将user_ids列表复制两次,如下所示:
#label
有没有办法编写这个查询而不用两次写入整个id列表?这是post-gres btw,但我认为它适用于所有SQL。
答案 0 :(得分:2)
您的LEFT
加入正在成为INNER
加入,因为您正在过滤where子句中的正确表格。
由于您的两个连接谓词都引用了相同的已过滤列user_id
,因此您可以将查询简化为:
SELECT
---columns---
FROM tbl_referrals REF
JOIN tbl_profile PRF1 ON REF.referring_user_id = PRF1.user_id
OR REF.referred_user_id = PRF1.user_id
WHERE PRF1.user_id IN ('id100','id200','id300','id400')
ORDER BY REF.referred_user_id
LIMIT 100;
修改评论:
您可以使用条件聚合来获取select的两个名称:
SELECT
MAX(CASE WHEN REF.referring_user_id = PRF1.user_id THEN PRF1.Name END) ReferringName,
MAX(CASE WHEN REF.referred_user_id = PRF1.user_id THEN PRF1.Name END) ReferredName,
---other columns---
FROM tbl_referrals REF
JOIN tbl_profile PRF1 ON REF.referring_user_id = PRF1.user_id
OR REF.referred_user_id = PRF1.user_id
WHERE PRF1.user_id IN ('id100','id200','id300','id400')
GROUP BY ---other columns---
ORDER BY REF.referred_user_id
LIMIT 100;
答案 1 :(得分:1)
您可以创建一个包含所需ID的迷你表,然后将其连接到现有表。这样您只需指定一次ID。它看起来像是:
SELECT
---columns---
FROM tbl_referrals REF
LEFT JOIN tbl_profile PRF1 ON REF.referring_user_id = PRF1.user_id
LEFT JOIN tbl_profile PRF2 ON REF.referred_user_id = PRF2.user_id
INNER JOIN
(
SELECT 'id100' AS id UNION ALL
SELECT 'id200' AS id UNION ALL
SELECT 'id300' AS id UNION ALL
SELECT 'id400' AS id
) IDS
on IDS.id = PRF1.user_id OR IDS.id = PRF2.user_id
ORDER BY REF.referred_user_id
limit 100;
答案 2 :(得分:0)
WITH ids(id) AS (VALUES('{id100,id200,id300,id400}'::text[]))
SELECT
---columns---
FROM tbl_referrals REF
JOIN ids ON (REF.referring_user_id = ANY(ids.id) OR REF.referred_user_id = ANY(ids.id))
LEFT JOIN tbl_profile PRF1 ON REF.referring_user_id = PRF1.user_id
LEFT JOIN tbl_profile PRF2 ON REF.referred_user_id = PRF2.user_id
ORDER BY REF.referred_user_id
limit 100;