每个项目获得5个结果 - Postgres

时间:2016-02-18 19:18:12

标签: sql postgresql

所以我有一个原因列表和一个匹配列表(一个包含两个外键的对象),并且对于符合某些条件的每个原因,我想得到前五个匹配的原因。但是我在做这件事时遇到了麻烦。

我开始使用此代码,选择所选原因的所有匹配

SELECT * FROM matches m
WHERE m.cause_id in (
    SELECT cz.id
        FROM causes cz
        WHERE (*condition*)

然后尝试加入,所以我可以限制它,但我还没有找到如何。

SELECT * FROM matches m
WHERE (*condition*)
JOIN causes cz ON m.cause_id = cz.id

????

'限制'限制最终结果的总数,我不能限制匹配的原因数量。建议?

2 个答案:

答案 0 :(得分:1)

如果我正确理解了这一点,你有一个由你申请的条件产生的原因列表,你想获得每个条件的前5个匹配?

如果这是正确的,你可以使用Window Functions来关闭它:

SELECT
    *
FROM
    (
        SELECT
            m.*,
            c.*,
            ROW_NUMBER() OVER (PARTITION BY c.id ORDER BY m.id) as rowcount
        FROM
            matches m JOIN causes c ON m.cause_id = c.id
    ) sub
WHERE sub.rowcount <=5

关键在于ROW_NUMBER() OVER (PARTITION BY c.id ORDER BY m.id) as rowcount,其中说“为每个不同的原因id创建一个从1开始的连续行号。按匹配ID排序编号”。然后我们只过滤那些小于或等于5的行数的结果。

答案 1 :(得分:1)

我不确定“前五”比赛是什么意思。使用LIMIT编写查询很有诱惑力,但我不确定这是什么意思:

SELECT m.*
FROM matches m
WHERE m.cause_id in (SELECT cz.id
                     FROM causes cz
                     WHERE (*condition*)
                     ORDER BY cz.id
                     LIMIT 5
                    );

相反,请使用row_number()

SELECT cm.*
FROM (SELECT m.*, ROW_NUMBER() OVER (PARTITION BY m.cause_id ORDER BY cz.id) as seqnum
      FROM matches m JOIN
           causes cz
           ON m.cause_id = cz.id
      WHERE (*condition*)
     ) cm
WHERE seqnum <= 5;

对于每个原因,这将返回五个匹配。