如何使用SQL聚合和折叠数据库表中的行?

时间:2014-12-10 14:36:27

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

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

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)和{ {1}}。

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列条目的行。

2 个答案:

答案 0 :(得分:1)

据我所知,没有"编辑到位"在Postgresql(或我能想到的任何其他传统RDBMS)中。代替:

  1. 获取查询结果并将其转储到临时表中:CREATE TEMP TABLE <temptable> AS <Your Query> WITH DATA
  2. 删除word表格中的所有内容:TRUNCATE word; &lt; - 这是一个可怕的部分,因此请在截断前确保您的查询很酷。
  3. 将临时表中的记录插入到现在为空的word表中:INSERT INTO word SELECT * FROM <temptable>;
  4. 可选:删除临时表DROP TABLE <temptable>;(作为临时表,当你结束会话时它将自动删除,但我是明确的粉丝)

答案 1 :(得分:0)

实际上 可以 使用数据修改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: