【问题标题】:How can I aggregate and collapse rows in a database table using SQL?如何使用 SQL 聚合和折叠数据库表中的行?
【发布时间】:2015-02-08 19:18:45
【问题描述】:

我有一个包含示例数据的表格,如下所示。

word       | last_seen  | first_seen | count
-----------|------------|------------|------
definition | 2014-09-08 | 2012-01-02 | 15
definition | 2014-10-11 | 2013-05-12 | 35
attribute  | 2013-07-23 | 2010-06-29 | 22

我想要对数据进行就地聚合,希望只使用 SQL,其中重复单词的数据使得我最终得到 MAX(last_seen)MIN(first_seen)SUM(count)

word       | last_seen  | first_seen | count
-----------|------------|------------|------
definition | 2014-10-11 | 2012-01-02 | 50
attribute  | 2013-07-23 | 2010-06-29 | 22

我知道我可以通过以下方式查看聚合结果:

SELECT 
  word, 
  MAX(last_seen) AS last_seen, 
  MIN(first_seen) AS first_seen, 
  SUM(count) AS count 
FROM 
  words 
GROUP BY word;

但是,我不只是想查看生成的聚合...我想实际更新 words 表,用聚合数据替换具有重复 word 列条目的行。

【问题讨论】:

  • 我不明白为什么你的代码没有给你想要的东西。你能详细说明一下I just don't know how to update the words table in-place with the results
  • 您至少有两条语句,一条要更新,一条要删除现在不相关的记录。
  • 您确定要更新现有表,还是只想查看包含聚合数据的视图?万一又变了呢?
  • 您可以使用 with 子句在一个查询中进行组合选择、更新和删除:postgresql.org/docs/9.3/static/sql-select.html

标签: sql postgresql aggregate-functions common-table-expression duplicate-removal


【解决方案1】:

据我所知,Postgresql(或我能想到的任何其他传统 RDBMS)中没有“就地编辑”。而是:

  1. 获取查询结果并将其转储到临时表中:CREATE TEMP TABLE <temptable> AS <Your Query> WITH DATA
  2. 删除word 表中的所有内容:TRUNCATE word;
  3. 将临时表中的记录插入到现在为空的word 表中:INSERT INTO word SELECT * FROM <temptable>;
  4. 可选:删除您的临时表 DROP TABLE <temptable>;(作为临时表,它会在您结束会话时自动删除,但我喜欢明确表示)

【讨论】:

    【解决方案2】:

    实际上,您可以使用数据修改 CTE 在单个语句中做到这一点:

    WITH del AS (
       DELETE FROM words w
       WHERE EXISTS (
          SELECT 1 
          FROM   words w1
          WHERE  w1.word = w.word
          AND    w1.ctid <> w.ctid
         )
       RETURNING *
       )
    INSERT INTO words(word, last_seen, first_seen, count)
    SELECT word, MAX(last_seen), MIN(first_seen), SUM(count)
    FROM   del
    GROUP  BY word;
    

    应该也相当有效率。

    SQL Fiddle.

    关于ctid

    关于 CTE:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-20
      • 2023-03-29
      相关资源
      最近更新 更多