根据订单和关键字段对字符串进行分组和聚合

时间:2016-06-17 13:55:01

标签: sql postgresql

我在PostegreSQL表中有数据如下所示:

text                     field1   field2    ID
Lorem ipsum dolor             A        B     1
Donec tristique ips           A        C     2
Donec ut imperdiet neque,     A        B     3
Suspendisse urna nunc,        A        B     4
tristique auctor libero.      A        C     5
sem varius nec                A        C     6

我想添加某种第二个ID,它按字段1和字段2对文本进行分组,同时保持表的顺序。像这样:

text                     field1   field2    ID    ID2
Lorem ipsum dolor             A        B     1      1
Donec tristique ips           B        C     2      2
Donec ut imperdiet neque,     A        B     3      3
Suspendisse urna nunc,        A        B     4      3
tristique                     B        C     5      4
sem varius nec                B        C     6      4
sem neque auctor              B        C     7      4  

然后我会根据该ID2字段对我的文本字段进行分组和聚合。 最终结果如下:

text                                                 field1    field2   ID2
Lorem ipsum dolor                                     A         B         1
Donec tristique ips                                   B         C         2 
Donec ut imperdiet neque, Suspendisse urna nunc,      A         B         3     
tristique sem varius necsem neque auctor              B         C         4 

为了获得此结果,我需要运行哪些查询?

谢谢,

1 个答案:

答案 0 :(得分:0)

您可以为任何聚合函数提供“内部”排序:

SELECT  array_agg(text ORDER BY id) AS text,
        field1, field2,
        row_number() OVER () AS id2
FROM    t
GROUP BY field1, field2
ORDER BY id2

如果您要打印结果或将其拉入应用程序,您可能更愿意使用string_agg代替array_agg,并使用,作为分隔符。

编辑:当field1按行排序时,以下是一个标识相同field2 + id值“运行”的查询:

SELECT  array_agg(text ORDER BY id),
        field1, field2,
        row_number() OVER ()
FROM    (
        SELECT  t.*,
                (SELECT MIN(t2.id)
                 FROM   t t2
                 WHERE  t2.id <= t.id
                 AND    t2.field1 = t.field1
                 AND    t2.field2 = t.field2
                 AND    NOT EXISTS (SELECT  1
                                    FROM    t t3
                                    WHERE   t3.id < t.id
                                    AND     t3.id > t2.id
                                    AND     (t3.field1 <> t.field1
                                    OR       t3.field2 <> t.field2))) AS g
        FROM    t
        ) AS x
GROUP BY g, field1, field2
ORDER BY g
;

我认为这个查询有点荒谬,而且我不保证它的性能,但它可以满足您的要求。此外,由于你似乎不愿意接受许多人解释表没有自然顺序,你应该找到一本关于关系模型的好书并阅读它。