PostgreSQL и сводные таблицы с использованием функции кросс-таблицы - PullRequest
2 голосов
/ 06 ноября 2011

У меня проблема с созданием сводной таблицы в PostgreSQL с использованием функции crosstab().Работает хорошо, но выдает несколько записей для одного и того же client_id.Как я могу избежать этого?

Вот SQL:

SELECT *
FROM crosstab('SELECT client_id
                     ,extract(year from date)
                     ,sum(amount)
               from   orders
               group  by extract(year from date)
                     ,client_id'
             ,'SELECT extract(year from date)
               FROM   orders
               GROUP  BY extract(year from date)
               order  by extract(year from date)')
AS orders(
row_name integer,
year_2001 text,
year_2002 text,
year_2003 text,
year_2004 text,
year_2005 text,
year_2006 text,
year_2007 text,
year_2008 text,
year_2009 text,
year_2010 text,
year_2011 text);

// Редактировать

Спасибо Эрвину это работает сейчас, но я пытался сделать это безвстроенная функция без удачи.Может кто-то предложить что-то по этому поводу?Мой код всего за два года:

SELECT DISTINCT o.client_id,
       CASE WHEN (extract(year from o.date)=2001)
            THEN sum(o.amount) ELSE 0 END,
       CASE WHEN (extract(year from o.date)=2002)
            THEN sum(o.amount) ELSE 0 END
FROM orders AS o
GROUP BY 1, extract(year from o.date)
ORDER BY 1;

1 Ответ

3 голосов
/ 06 ноября 2011

Вам необходимо ORDER BY первый запрос соответственно.Я использую упрощенный синтаксис ORDER BY <ordinal number> здесь.

SELECT *
FROM   crosstab(
        'SELECT client_id
               ,extract(year from date)
               ,sum(amount)
         FROM   orders
         GROUP  BY 1,2
         ORDER  BY 1,2',

        'SELECT extract(year from date)
         FROM   orders
         GROUP  BY 1
         ORDER  BY 1')
AS orders(
    row_name integer,
    year_2001 text,
    year_2002 text,
    year_2003 text,
    year_2004 text,
    year_2005 text,
    year_2006 text,
    year_2007 text,
    year_2008 text,
    year_2009 text,
    year_2010 text,
    year_2011 text);

Функция crosstab() не включена в стандартный PostgreSQL, но поставляется с дополнительным модулем tablefunc .

Изменить для дополнительного запроса

Версия без функции crosstab(): Группировать можно только по client_id, или вы получите несколько строк на client_id.

SELECT client_id
      ,sum(CASE WHEN extract(year from date) = 2001 THEN amount ELSE 0 END) AS year_2001
      ,sum(CASE WHEN extract(year from date) = 2002 THEN amount ELSE 0 END) AS year_2002
       -- ...
FROM   orders o
GROUP  BY 1
ORDER  BY 1;
...