SQL для получения результата от одного запроса в виде столбцов к другому запросу

#sql #postgresql

#sql #postgresql

Вопрос:

Допустим, у меня есть эти две таблицы:

 CREATE TABLE nodes
(
    id      INTEGER PRIMARY KEY,
name    TEXT
);

CREATE TABLE events
(
    id      INTEGER PRIMARY KEY,
    node    INTEGER REFERENCES nodes,
    etime   TIMESTAMP,
    value   TEXT
);
  

Существует ли запрос для получения значений из nodes таблицы в виде столбцов в events таблицу?

Для простого примера я хотел бы что-то вроде этого:

  node1 |  node2 |  node3
------- -------- --------
event1 |        |
       | event2 |
       |        | event3
  

Возможно ли это?

Чего я действительно хотел бы, так это SQL-запроса, который мог бы выводить что-то вроде этого:

        etime        |  node1  |  node2  |  node3
-------------------- --------- --------- --------
2011-04-26 13:12:23 | Event 1 |         | Event 2
2011-04-26 15:52:43 |         | Event 3 |        
2011-04-26 21:35:12 | Event 4 | Event 5 | Event 6
  

Где node1 to node3 берется из node таблицы, а временные метки и Event тексты берутся из events таблицы.

Ответ №1:

Это называется перекрестной таблицей или сводным запросом, и не существует SQL-совместимого способа его создания.

Быстрый поиск в Google показывает, что для PostgreSQL есть модуль contrib (похоже, что сейчас в core).

Еще одно довольно интересное сообщение в блоге здесь (первое в Google) — хотя это не полностью перекрестная таблица, поскольку в ней фиксированное количество столбцов.

Комментарии:

1. Семейство функций перекрестных таблиц выглядит многообещающе. Мне придется немного поэкспериментировать с этим.

Ответ №2:

Используйте группировку и агрегирование по выражениям CASE:

 SELECT
  e.etime,
  MIN(CASE n.name WHEN 'node1' THEN e.value END) AS node1,
  MIN(CASE n.name WHEN 'node2' THEN e.value END) AS node2,
  MIN(CASE n.name WHEN 'node3' THEN e.value END) AS node3
FROM events e
  INNER JOIN nodes n ON e.node = n.id
GROUP BY