2

鉴于以下情况:

CREATE TABLE A (A1 INTEGER, A2 INTEGER, A3 INTEGER);

INSERT INTO A(A1, A2, A3) VALUES (1, 1, 1);
INSERT INTO A(A1, A2, A3) VALUES (2, 1, 1);

我想选择A1给定的最大值A2A3值,并让这些值 (A2A3) 也出现在返回的行中(例如,这样我就可以在连接中使用它们,因为下面的 SELECT 用于子查询)。

WHERE鉴于 A2 和 A3 在子句中是硬编码的,因此能够执行以下操作似乎是合乎逻辑的:

SELECT MAX(A1) AS A1, A2, A3 FROM A WHERE A2=1 AND A3=1

然而,PostgreSQL(我也怀疑其他 RDBM)对此犹豫不决,并请求 A2 和 A3 的聚合函数,即使它们的值是固定的。所以相反,我要么必须做一个:

SELECT MAX(A1) AS A1, MAX(A2), MAX(A3) FROM A WHERE A2=1 AND A3=1

或:

SELECT MAX(A1) AS A1, 1, 1 FROM A WHERE A2=1 AND A3=1

我不喜欢第一个替代方案,因为我可以使用MIN它并且它仍然可以工作,而第二个替代方案将位置参数的数量增加一倍,以便在从编程语言界面使用时提供值。理想情况下,我会想要一个UNIQUE聚合函数,它可以断言所有值都相等并返回该单个值,或者甚至是RANDOM一个随机返回一个值的聚合函数(因为我从WHERE子句中知道它们都是相等的)。

有没有一种惯用的方式在 PostgreSQL 中编写上述内容?

4

4 回答 4

1

更简单,你只需要ORDER BY/LIMIT 1

SELECT a1, a2, a3      -- add more columns as you please
FROM   a
WHERE  a2 = 1 AND a3 = 1
ORDER  BY 1 DESC      -- 1 is just a positional reference (syntax shorthand)
LIMIT  1;

LIMIT 1是 Postgres 特定的语法。SQL 标准
是:

...
FETCH FIRST 1 ROWS ONLY

我的第一个答案DISTINCT ON是针对更复杂的情况,您希望检索a1各种组合的最大值(a2,a3)

旁白:我使用小写标识符是有原因的

于 2013-11-22T17:22:46.247 回答
1

分组如何

select 
a2
,a3
,MAX(a1) as maximumVal
from a
group by a2, a3
于 2013-11-22T16:27:16.587 回答
1

这对你有用吗?

select max(A1),A2,A3 from A GROUP BY A2,A3;

编辑

select A1,A2,A3 from A where A1=(select max(A1) from A ) limit 1
于 2013-11-22T16:25:38.200 回答
0

在没有聚合函数的情况下获得最大行的标准技巧是通过 NOT EXISTS 子查询来保证不存在更大的值。(这在有平局时不起作用,但具有最大值的子查询也不会)当需要时,添加平局条件不会太难。

另一种解决方案是带有窗口函数的子查询row_number()rank()

SELECT *
FROM a src
WHERE NOT EXISTS ( SELECT * FROM a nx
    WHERE nx.a2 = src.a2
    AND nx.a3 = src.a3
    AND nx.a1 > src.a1
    );
于 2013-11-22T17:25:38.910 回答