Создать Postgresql кросс-таблицу запросов с несколькими категориями - PullRequest
0 голосов
/ 25 апреля 2020

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

+------------+----------+-------------+-------+
|    date    | category | subcategory | count |
+------------+----------+-------------+-------+
| 2020-04-23 | One      | First       |     1 |
| 2020-04-23 | Two      | Second      |     1 |
| 2020-04-23 | Two      | First       |     3 |
| 2020-04-23 | Three    | Third       |     3 |
| 2020-04-23 | Three    | Second      |     1 |
| 2020-04-23 | Four     | Second      |     2 |
| 2020-04-23 | Five     | Third       |     3 |
| 2020-04-23 | Five     | Second      |     1 |
| 2020-04-23 | Five     | First       |     1 |
| 2020-04-23 | Six      | Third       |     1 |
| 2020-04-23 | Six      | Second      |     2 |
+------------+----------+-------------+-------+

Я хотел бы превратить его в следующее, но не могу понять:

+------------+----------+-------+--------+-------+
|    date    | category | First | Second | Third |
+------------+----------+-------+--------+-------+
| 2020-04-23 | One      |     1 |      0 |     0 |
| 2020-04-23 | Two      |     2 |      3 |     0 |
| 2020-04-23 | Three    |     0 |      1 |     3 |
| 2020-04-23 | Five     |     1 |      2 |     3 |
| 2020-04-23 | Six      |     0 |      2 |     1 |
+------------+----------+-------+--------+-------+

Я попробовал следующее, но выглядит так, как будто вы должны вернуть строку, столбец и значение при использовании кросс-таблицы , чтобы она не работала:

SELECT *
FROM crosstab(
    $$
        SELECT date, category, subcategory, count(*)
        -- ...
        GROUP BY 1, 2, 3
    $$
)
AS ct(date date, category text, First int, Second int, Third int);

Is Есть ли способ использовать несколько значений для индикатора строки при использовании кросс-таблицы, или мне нужно будет найти какой-то другой подход?

1 Ответ

0 голосов
/ 27 апреля 2020

Я нашел решение, хотя и не идеальное: объединить первые два с уникальным символом, получить перекрестный запрос с помощью CTE и разбить получившиеся столбцы. Это выглядит примерно так:

WITH crosstb AS (
    SELECT *
    FROM crosstab(
        $$
        -- Concatenate date and category columns
        SELECT date || '_' || category, subcategory, count(*)
        -- ...
        GROUP BY 1, 2
        $$,
        -- Specify data columns to ensure null-count rows are included
        $$VALUES ('First'), ('Second'), ('Third')$$
    )
    AS ct(datecat text, First numeric, Second numeric, Third numeric)
)
SELECT 
    -- Split datecat column into separate again
    (regexp_split_to_array(datecat, '_'))[1]::date as Date, 
    (regexp_split_to_array(datecat, '_'))[2] as category, 
    COALESCE(First, 0),
    COALESCE(Second, 0),
    COALESCE(Third, 0)
FROM crosstb;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...