假设我有以下表格:
table_1 table_2
id_a name id_a id_b
1 c 1 1
2 a 1 2
3 b 2 1
2 2
现在考虑以下LEFT OUTER JOIN:
SELECT *
FROM table_1
LEFT OUTER JOIN table_2 USING (id_a)
id_a name id_b
1 c 1
1 c 2
2 a 1
2 a 2
3 b
现在想象'FROM table_1'实际上是一个复杂的子查询,如:
SELECT * FROM huge_table WHERE expensive_conditions_producing_three_rows
是否可以编写仅以最小名称连接左行的查询,而无需完全重新运行子查询?您可以假设您对子查询有一定的控制权,即您可以根据需要添加ORDER BY。
换句话说,最终结果应如下所示:
id_a name id_b
1 c
2 a 1
2 a 2
3 b
我考虑使用SELECT INTO将子查询结果放在临时表中。那么计算JOIN ON条件下使用的最小值不会有问题。但我宁愿避免这种情况,除非它是唯一的解决方案。
编辑:我会等待几天,然后接受最佳解决方案,无论PG版本如何。但是,非常感谢PG 8.3及更早版本中的一个。
答案 0 :(得分:5)
使用Window functions(可从PostgreSQL 8.4获得):
SELECT *
FROM
( SELECT *
, ROW_NUMBER() OVER (ORDER BY SomeColumn) AS RowNum
FROM table_1
) AS a
LEFT JOIN
table_2 AS b
ON
(join condition)
AND
a.RowNum = 1
答案 1 :(得分:3)
使用CTE (common table expression)(适用于PostgreSQL 8.4或更高版本):
WITH cte AS (
SELECT id_a, name
FROM table_1
WHERE expensive_conditions_producing_three_rows
)
SELECT c.id_a, c.name, t2.id_b
FROM cte c
LEFT JOIN table2 t2 ON t2.id_a = c.id_a
AND t2.name = (SELECT min(name) FROM cte)