从组合字符串中获取组最大值
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 项:001
、2016
、TT
和 000001
。
如何提取前 3 项组成的每个组的最大值?我想要的结果是这样的:
001/2017/TT/000003
001/2017/TN/000002
001/2016/TT/000002
002/2016/TT/000002
编辑
- 子字段分隔符是
/
,子字段的长度可以变化。
- 我使用 PostgreSQL 9.3。
使用 LEFT
和 RIGHT
函数。
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 类型的数据项 可能 的行为与其字符串表示形式不同。 900001
和 1000001
的最大值对于 text
是 900001
,对于 integer
是 1000001
...
看看这个,可能有用
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;
我有一个 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 项:001
、2016
、TT
和 000001
。
如何提取前 3 项组成的每个组的最大值?我想要的结果是这样的:
001/2017/TT/000003
001/2017/TN/000002
001/2016/TT/000002
002/2016/TT/000002
编辑
- 子字段分隔符是
/
,子字段的长度可以变化。 - 我使用 PostgreSQL 9.3。
使用 LEFT
和 RIGHT
函数。
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 类型的数据项 可能 的行为与其字符串表示形式不同。 900001
和 1000001
的最大值对于 text
是 900001
,对于 integer
是 1000001
...
看看这个,可能有用
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;