0

У меня есть таблица с примерами данных, как показано ниже.Как я могу агрегировать и свернуть строки в таблице базы данных с помощью SQL?

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 записей столбцов с агрегированными данными.

+1

Я не понимаю, почему ваш код не дает вам то, что вы хотите. можете ли вы подробно остановиться на «Я просто не знаю, как обновить таблицу слов на месте с результатами». – Matt

+0

У вас есть как минимум два оператора, один для обновления, а другой - для удаления уже несущественной записи. – paqogomez

+0

Вы действительно хотите обновить существующую таблицу или просто хотите получить представление с агрегированными данными? Что, если он снова изменится? – sgeddes

ответ

1

Насколько я знаю, в Postgresql (или каких-либо других традиционных СУБД, о которых я могу думать) нет «Редактировать на месте». Вместо этого:

  1. Возьмите результаты запроса и сбросить их в временную таблицу: CREATE TEMP TABLE <temptable> AS <Your Query> WITH DATA
  2. Удалить все, в вашем word таблице: TRUNCATE word;< --This это страшная часть поэтому убедитесь, что вы круты с вашим запросом перед усечением.
  3. Вставьте записи в вашей временную таблицу в опустевшую word таблице: INSERT INTO word SELECT * FROM <temptable>;
  4. Необязательно: Бросай временную таблицу DROP TABLE <temptable>; (будучи временную таблицу, она будет падать автоматически при завершении сеанса, но я фанат быть явным)
+0

Спасибо! Это сработало отлично. – Bryan

0

на самом деле вы может сделать в одном операторе с помощью КТРА данных модифицирующих:

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 О:

О КТР: