从组合字符串中获取组最大值

Get group maxima from combined strings

我有一个 table,其列 code 包含多个数据,如下所示:

001/2017/TT/000001
001/2017/TT/000002
001/2017/TN/000003
001/2017/TN/000001
001/2017/TN/000002
001/2016/TT/000001
001/2016/TT/000002
001/2016/TT/000001
002/2016/TT/000002

001/2016/TT/000001中有 4 项:0012016TT000001
如何提取前 3 项组成的每个组的最大值?我想要的结果是这样的:

001/2017/TT/000003
001/2017/TN/000002
001/2016/TT/000002
002/2016/TT/000002

编辑

使用 LEFTRIGHT 函数。

SELECT MAX(RIGHT(code,6)) AS MAX_CODE
FROM yourtable
GROUP BY LEFT(code,12)

显然,您应该 规范化 table 并将组合的字符串拆分为具有适当数据类型的 4 列。如果分隔符 '/' 在您的字符串中保持不变并且长度可以变化,则函数 split_part() 是首选工具。

CREATE TABLE tbl_better AS 
SELECT split_part(code, '/', 1)::int AS col_1  -- better names?
     , split_part(code, '/', 2)::int AS col_2
     , split_part(code, '/', 3)      AS col_3  -- text?
     , split_part(code, '/', 4)::int AS col_4
FROM   tbl_bad
ORDER  BY 1,2,3,4  -- optionally cluster data.

那么任务就很简单了:

SELECT col_1, col_2, col_3, max(col_4) AS max_nr
FROM   tbl_better
GROUP  BY 1, 2, 3;

相关:

  • Split comma separated column data into additional columns

当然,您也可以即时完成。对于不同的子字段长度,您可以使用 substring() 和这样的正则表达式:

SELECT max(substring(code, '([^/]*)$')) AS max_nr
FROM   tbl_bad
GROUP  BY substring(code, '^(.*)/');

相关(对正则表达式模式的基本解释):

或者仅获取完整的字符串作为结果:

SELECT DISTINCT ON (substring(code, '^(.*)/'))
       code
FROM   tbl_bad
ORDER  BY substring(code, '^(.*)/'), code DESC;

关于DISTINCT ON

  • Select first row in each GROUP BY group?

请注意,转换为 suitable 类型的数据项 可能 的行为与其字符串表示形式不同。 9000011000001 的最大值对于 text900001,对于 integer1000001 ...

看看这个,可能有用

select 
distinct on (tab[4],tab[2]) tab[4],tab[3],tab[2],tab[1]
from
(
    select
    string_to_array(exe.x,'/') as tab,
    exe.x
    from
    (
        select
        unnest
            (
            array
            ['001/2017/TT/000001',
            '001/2017/TT/000002',
            '001/2017/TN/000003',
            '001/2017/TN/000001',
            '001/2017/TN/000002',
            '001/2016/TT/000001',
            '001/2016/TT/000002',
            '001/2016/TT/000001',
            '002/2016/TT/000002']
            ) as x
    ) exe
) exe2
order by tab[4] desc,tab[2] desc,tab[3] desc;