如何按字符串的一部分选择和分组?

时间:2010-05-25 17:31:29

标签: sql postgresql string group-by grouping

鉴于我有以下数据,如何按字符串的部分选择和分组?

Version  Users
1.1.1    1
1.1.23   3
1.1.45   1
2.1.24   3
2.1.12   1
2.1.45   3
3.1.10   1
3.1.23   3

我想要的是使用版本1.1.x和2.2.x和3.3.x等来总结用户,但我不确定如何在select语句中对部分字符串进行分组。

修改 数据应该返回的是:

Version  Users
1.1.XX   5
2.1.XX   7
3.1.XX   4

有一个无限可变数量的版本,有些是这种格式(主要,次要,构建),有些只是主要的,次要的,有些只是主要的,我唯一想要“卷起”版本的时候是有一个版本。

3 个答案:

答案 0 :(得分:4)

select rtrim(Version, '0123456789') ||'XX', sum(users) 
from Table
group by rtrim(Version, '0123456789')

答案 1 :(得分:2)

Postgres substring(string from pattern) 函数也支持正则表达式。这使得对于复杂字符串也很容易解决这个问题,其中具有固定开始和长度的 rtrimsubstring 不起作用。

示例(substring(string, pattern) 是简写,from 可以省略):

WITH x ("Version", "Users") AS (
select '1.1.1', 1 union all
select '1.1.23', 3 union all
select '1.1.45', 1 union all
select '2.1.24', 3 union all
select '2.1.12', 1 union all
select '2.1.45', 3 union all
select '3.1.10', 1 union all
select '3.1.23', 3)
select
  substring(x."Version", '([0-9]*\.[0-9]*)\.[0-9]*') || '.XX' as "Version",
  sum("Users") as "Users"
from x
group by
  substring(x."Version", '([0-9]*\.[0-9]*)\.[0-9]*');

请注意,我们使用带括号的子表达式仅返回匹配的一部分,并且示例中省略了 is not null。这导致:

Version Users
1.1.XX  5
2.1.XX  7
3.1.XX  4

来自documentation

<块引用>

带两个参数的子串函数,substring(string from 模式),提供与 POSIX 匹配的子字符串的提取 正则表达式模式。如果没有匹配,则返回 null, 否则匹配模式的文本部分。但如果 模式包含任何括号,匹配的文本部分 第一个带括号的子表达式(左括号 先来)返回。你可以在整个周围加上括号 如果您想在不触发的情况下在其中使用括号,则表达式 这个例外。如果在模式之前需要括号 要提取的子表达式,请参阅非捕获括号 如下所述。

注意:上面省略了(major, minor)或only (major)形式的版本处理逻辑。您也可以轻松地将这些分组,例如通过将正则表达式更改为 ([0-9]*|[0-9]*\.[0-9]*),但我不明白这有什么意义。例如。如果您有“1”、“1.2”、“1.2.3”,仅按专业分组 会更合理:“1”可以表示任何内容,从“1.0.0”到“1.2”。 4' 但它也可能表示 '1.2.3'。

答案 2 :(得分:1)

在第一部分分组后,您没有指定要查看的内容,也没有指定每个分部长度的任何规格。假设您想要用户数,并且每个部分不超过一个字符(即,没有10.1.xxx,也没有10.10.xxx):

Select substring(Version, 1, 3), Count(*)
From Table
Group By substring(Version, 1, 3)