PostgreSQL - 避免两次列出相同的IN()值

时间:2017-11-16 19:14:54

标签: sql postgresql

我在客户推介表上有一个查询,其中每行包含推荐客户的客户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。

3 个答案:

答案 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;