查询最高版本

hdc*_*hdc 3 postgresql sql-server greatest-n-per-group

我有下表(剥离到基本要素):(脚本在 postgresql 中)

CREATE TABLE t_version (
  name VARCHAR(64) NOT NULL,
  major INTEGER NOT NULL,
  minor INTEGER NOT NULL,
  attr VARCHAR(64)
);

ALTER TABLE t_version
  ADD CONSTRAINT PK_VERSION
  PRIMARY KEY (name, major, minor);
Run Code Online (Sandbox Code Playgroud)

以及一些测试数据:

INSERT INTO t_version (name, major, minor, attr) VALUES ('n1', 1, 0, 'a1');
INSERT INTO t_version (name, major, minor, attr) VALUES ('n1', 1, 1, 'a2');
INSERT INTO t_version (name, major, minor, attr) VALUES ('n1', 2, 0, 'a3');
Run Code Online (Sandbox Code Playgroud)

我想弄清楚,如何从中选择最高版本,即一个可以给我的选择

'n1', 2, 0, 'a3'

其结果。

我知道如何做到这一点,当只需要最高的次要版本时:

SELECT A.name, A.major, A.minor, A.attr
  FROM t_version AS A
    JOIN (
           SELECT name, major, 
             max(minor) AS minor
           FROM t_version
           GROUP BY name, major
         ) LATEST
      ON A.name = LATEST.name
         AND A.major = LATEST.major
         AND A.minor = LATEST.minor;
Run Code Online (Sandbox Code Playgroud)

但我对更普遍的问题不知所措。

顺便说一句,该解决方案不仅适用于 sql server 的 postgresql。

a_h*_*ame 8

问题通常使用窗口函数来解决。

以下是标准 SQL,也适用于 SQL Server:

select name, major, minor, attr
from (
  select name, major, minor, attr, 
         row_number() over (partition by name order by major desc, minor desc) as rn
  from t_version
) t
where rn = 1
order by name;
Run Code Online (Sandbox Code Playgroud)

对于 Postgres,使用它通常会更快distinct on ()

select distinct on (name) name, major, minor, attr
from t_version
order by name, major desc, minor desc;
Run Code Online (Sandbox Code Playgroud)