SQL INNER JOIN:ORDER BY LIMIT 来自一个 table
SQL INNER JOIN: ORDER BY LIMIT duplicates from one table
我有 2 个 table 之间没有相同的主键(id
存在于两者中,主键仅用于 table A
)。我想将第一个 table A
的主键用于 ON
子句。因此,我将复制第二个 table 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
;
查询return的单条记录。虽然所需的行为是 return 单条记录,但仅针对 B
中具有相同 id
的每组记录(基于所提到的标准)。所以总共查询当然会 return 多条记录...
怎样才能达到预期的效果?
谢谢,
你的问题应该是这一行:
(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
;
使用rank()window解析函数,见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;
我有 2 个 table 之间没有相同的主键(id
存在于两者中,主键仅用于 table A
)。我想将第一个 table A
的主键用于 ON
子句。因此,我将复制第二个 table 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
;
查询return的单条记录。虽然所需的行为是 return 单条记录,但仅针对 B
中具有相同 id
的每组记录(基于所提到的标准)。所以总共查询当然会 return 多条记录...
怎样才能达到预期的效果?
谢谢,
你的问题应该是这一行:
(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
;
使用rank()window解析函数,见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;