SQL INNER JOIN:ORDER BY LIMIT从一个表

时间:2017-05-28 08:11:44

标签: sql postgresql inner-join limit

我有2个表,它们之间没有相同的主键(id存在于两者中,仅适用于表A)。我想使用第一个表A的主键作为ON子句。因此,我将从第二个表B中获得重复项。我希望基于某个字段GROUP BY B.cnt重复项,并始终选择第一个 - DESC LIMIT 1

这就是我尝试过的(DBMS是PostgreSQL):

SELECT 
    scheme1.A.some_attr, 
    B.some_attr
FROM 
    (SELECT * FROM scheme2.B ORDER BY scheme2.B.cnt DESC LIMIT 1) AS B
INNER JOIN
    scheme1.A
ON
    scheme1.A.id = B.id
;

查询返回单个记录。虽然期望的行为是仅为具有相同B的{​​{1}}的每组记录返回单个记录(基于所提到的标准)。所以总的来说,查询当然会返回多条记录......

如何达到预期效果?

谢谢,

2 个答案:

答案 0 :(得分:1)

你的问题应该是这一行:

(SELECT * FROM scheme2.B ORDER BY scheme2.B.cnt DESC LIMIT 1) scheme2.B

它被视为以下内容:

(SELECT * FROM scheme2.B ORDER BY scheme2.B.cnt DESC LIMIT 1) AS scheme2.B

如果scheme.B别名明显不正确,请将其更改为以下内容并且应该有效

SELECT 
    scheme1.A.some_attr, 
    scheme2.B.some_attr
FROM 
    (SELECT * FROM scheme2.B ORDER BY scheme2.B.cnt DESC LIMIT 1) AS B
INNER JOIN
    scheme1.A
ON
    scheme1.A.id = B.id
;

编辑:

SELECT 
    scheme1.A.some_attr, 
    scheme2.B.some_attr
FROM 
    scheme1.A
LEFT JOIN LATERAL
    (SELECT * FROM scheme2.B WHERE scheme2.B.id = scheme2.A.id ORDER BY scheme2.B.cnt DESC LIMIT 1) AS B ON TRUE
;

如果它是单个属性,您可以执行以下操作:

SELECT 
    scheme1.A.some_attr, 
    (
        SELECT 
            scheme2.B.some_attr
        FROM
            scheme2.B
        WHERE
            scheme2.B.id = scheme2.A.id
        ORDER BY scheme2.B.cnt DESC LIMIT 1
    )
FROM 
    scheme1.A
;

答案 1 :(得分:1)

使用rank()窗口分析函数,请参阅Postgres Window Functions

SELECT * FROM (
                SELECT          
                scheme1.A.some_attr, 
                scheme2.B.some_attr,                     
                rank() OVER (PARTITION BY B.ID ORDER BY scheme2.B.cnt, scheme2.B.another_attr DESC) as rnk
                FROM 
                                scheme1.A
                INNER JOIN
                                scheme2.B
                ON
                                scheme2.B.id = scheme2.A.id
) A WHERE rnk = 1;