Postgresql Pivot? Перекрестный? - PullRequest
       6

Postgresql Pivot? Перекрестный?

6 голосов
/ 01 декабря 2010

У меня есть таблица (которая является результатом запроса) в postgres, которая имеет набор строк (результат сложного суммирования данных), который выглядит следующим образом: (имена столбцов - это имена каждого дня) и значение каждого столбца имеет двойную точность.)

вс пн вт ср. Пт пт
1,24 1,11 4,51 3,21 2,21 1,01

Мне нужно, чтобы данные были выбраны из одной строки, чтобы результаты выглядели следующим образом:

Сумма в день
Вс 1.24
Пн 1.11
Вт 4.51
Ср 3,21
Чт 2.21
Пт 1.01

У меня трудности с началом работы, поскольку мне действительно нужно изменить имена столбцов на значения и изменить результат. Я попытался поэкспериментировать с кросс-таблицей, но не совсем уверен, что это то, что мне нужно. Буду очень признателен за любые советы или предложения, которые помогут мне двигаться в правильном направлении.

Ответы [ 3 ]

3 голосов
/ 15 июня 2011

Изменение первого ответа @Jack Douglas:

SELECT unnest(array['sun', 'mon', 'tue', 'wed', 'thu', 'fri']) AS day,
       unnest(array[sun, mon, tue, wed, thu, fri]) AS amount
FROM t;

Немного дешевле в соответствии с планировщиком запросов 9.0:

Seq Scan on t (cost=0.00..11.62 rows=360 width=192)

против

Subquery Scan on z (cost=0.00..12.16 rows=360 width=68) -> Seq Scan on t (cost=0.00..11.26 rows=360 width=192)

1 голос
/ 08 декабря 2010

тестовые объекты:

create table t ( sun numeric, 
                 mon numeric, 
                 tue numeric, 
                 wed numeric, 
                 thu numeric, 
                 fri numeric );

insert into t(sun, mon, tue, wed, thu, fri)
values(1.24, 1.11, 4.51, 3.21, 2.21, 1.01);

альтернатива ответу @ Unreason без union:

select day[i], amount[i]
from ( select generate_series(1,6) as i, 
              array['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri'] as day, 
              array[sun, mon, tue, wed, thu, fri] as amount
       from t ) z;

если вам нужно быть более общим, вы можете сделать что-то вроде этого:1008 *

create or replace function unpivot(t) returns setof record 
                           language plpgsql immutable strict as $$
declare
  q record;
  r record;
begin
  for q in ( select attname, attnum 
             from pg_attribute 
             where attnum>0 and attrelid = ( select oid 
                                             from pg_class 
                                             where relname = 't' ) ) loop 
    for r in execute 'select '''||q.attname||'''::text, '||
                             '('||$1::text||'::t).'||q.attname||'::numeric' loop
      return next r;
    end loop;
  end loop;
  return;
end;$$;

select *
from unpivot((select row(t.*)::t from t)) 
       as foo(day text, amount numeric);

Вы можете быть немного аккуратнее в 8.4 с предложением using в execute, но я не могу проверить это, поскольку я на 8.3

0 голосов
/ 02 декабря 2010

Я не знаю о прямой реализации, но, возможно, что-то вроде http://www.mail-archive.com/dhis2-users@lists.launchpad.net/msg00109.html может помочь вам начать

Конечно, если вам не нужно гибкое решение, вы можете сделать

SELECT 'Sun' AS Day, Sun AS Value FROM TABLE WHERE ...
UNION ALL
SELECT 'Mon' AS Day, Mon AS Value FROM TABLE WHERE ...
UNION ALL
SELECT 'Tue' AS Day, Tue AS Value FROM TABLE WHERE ...
UNION ALL
SELECT 'Wed' AS Day, Wed AS Value FROM TABLE WHERE ...
UNION ALL
SELECT 'Thu' AS Day, Thu AS Value FROM TABLE WHERE ...
UNION ALL
SELECT 'Fri' AS Day, Fri AS Value FROM TABLE WHERE ...

(суббота?)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...