基于标准聚合文本

Posted

技术标签:

【中文标题】基于标准聚合文本【英文标题】:Aggregate text based on a criteria 【发布时间】:2016-09-26 15:36:15 【问题描述】:

在previous question 上,我问了一个类似的问题,该问题依赖于帮助表作为拆分数据的标准的一部分。看来我目前的目标比较容易,但我想不通。

给定表格:

CREATE TABLE conversations (id int, record_id int, is_response bool, text text);
INSERT INTO conversations VALUES
  (1,  1,  false, 'in text 1')
, (2,  1,  true , 'response text 1')
, (3,  1,  false, 'in text 2')
, (4,  1,  true , 'response text 2')
, (5,  1,  true , 'response text 3')
, (6,  2,  false, 'in text 1')
, (7,  2,  true , 'response text 1')
, (8,  2,  false, 'in text 2')
, (9,  2,  true , 'response text 2')
, (10, 2,  true , 'response text 3');

我想根据is_response 值聚合文本并输出以下内容:

 record_id | aggregated_text                                   |
 ----------+---------------------------------------------------+
 1         |in text 1 response text 1                          |
 ----------+---------------------------------------------------+
 1         |in text 2 response text 2 response text 3          |
 ----------+---------------------------------------------------+
 2         |in text 1 response text 1                          |
 ----------+---------------------------------------------------+
 2         |in text 2 response text 2 response text 3          |

我试过下面的查询,但是没能连续聚合两个响应,IE :is_response 依次为真。

SELECT
    record_id,
    string_agg(text, ' ' ORDER BY id) AS aggregated_text
FROM (
    SELECT
        *,
        coalesce(sum(incl::integer) OVER (ORDER BY id ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING),0) AS grp
    FROM (
        SELECT *, is_response as incl
        FROM conversations
         ) c
     ) c1
GROUP BY record_id, grp
HAVING bool_or(incl)
ORDER BY max(id);

我的查询的输出只是为下面的 is_response 行添加了另一行,如下所示:

 record_id | aggregated_text                                   |
 ----------+---------------------------------------------------+
 1         |in text 1 response text 1                          |
 ----------+---------------------------------------------------+
 1         |in text 2 response text 2                          |
 ----------+---------------------------------------------------+
 1         |response text 3                                    |
 ----------+---------------------------------------------------+
 2         |in text 1 response text 1                          |
 ----------+---------------------------------------------------+
 2         |in text 2 response text 2                          |
 ----------+---------------------------------------------------+
 2         | response text 3                                   |
 ----------+---------------------------------------------------+

我该如何解决?

【问题讨论】:

看起来你需要一个窗口函数给我。 感谢您的回复,您能帮忙提供一个代码示例吗? 现在没有时间。只是想提供一个指针以供研究。 你看到我对你重复的问题的回答了吗? 我冒昧地将您的测试表作为CREATE TABLE 脚​​本提供。这是首选形式,使回答更容易。请记住提供您的 Postgres 版本。否则我们只能假设当前版本,这通常会引起混淆。 【参考方案1】:

这是我在您的previous question 中提供的answer 的变体:

SELECT record_id, string_agg(text, ' ')
FROM (
    SELECT *, coalesce(sum(incl::integer) OVER w,0) AS subgrp
    FROM (
        SELECT *, is_response AND NOT coalesce(lead(is_response) OVER w,false) AS incl
        FROM conversations
        WINDOW w AS (PARTITION BY record_id ORDER BY id)
    ) t
    WINDOW w AS (PARTITION BY record_id ORDER BY id ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING)
) t1
GROUP BY record_id, subgrp
HAVING bool_or(incl)
ORDER BY min(id);

我们的想法是,对于每一行,我们在 lead 窗口函数的帮助下查看同一记录的下一行。如果没有这样的行,或者如果有一个并且它的is_response 为假而当前的is_response 为真,那么我们选择该行,聚合所有以前未使用的text 值。

此查询还确保如果最后一个对话不完整(在您的示例数据中不会发生),它将被省略。

【讨论】:

【参考方案2】:

这基本上是your previous question 的更简单版本。

SELECT record_id, string_agg(text, ' ') As context
FROM  (
   SELECT *, count(NOT is_response OR NULL) OVER (PARTITION BY record_id ORDER BY id) AS grp
   FROM   conversations
   ORDER  BY record_id, id
   ) sub
GROUP  BY record_id, grp
ORDER  BY record_id, grp;

在子查询中使用单个窗口函数然后聚合。

我对您上一个问题的回答中的详细解释和链接:

Select partitions based on matches in other table

【讨论】:

并且它不会聚合多个 false is_response:意思是当连续有 2 个“in text”或更多时,它只会聚合第二个 @ShlomiSchwartz:这些都不是你的问题。聚合响应前一行的行似乎也没有意义。 我的描述性不够。然而,收集这些行确实有意义,因为上下文是随着时间的推移而建立的,请查看 my question 它可以更清楚地解释我的目标。再次感谢您的帮助!

以上是关于基于标准聚合文本的主要内容,如果未能解决你的问题,请参考以下文章

如何为基于聚合物的网页创建点击事件

分组和求和,使用非聚合标准来确定字段选择

pandas使用groupby函数agg函数获取每个分组聚合对应的标准差(std)实战:计算分组聚合单数据列的标准差(std)计算分组聚合多数据列的标准差(std)

2019-05-17 LACP 链路聚合以及配置实例

走进MongoDB

AEM 6.2 - 使用 Web 组件(聚合物)和 Angular