【问题标题】:Create Postgresql Crosstab Query with multiple categories创建具有多个类别的 Postgresql 交叉表查询
【发布时间】:2020-04-24 22:43:52
【问题描述】:

到目前为止,我已经创建了一个可以给我以下结果的查询:

+------------+----------+-------------+-------+
|    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 |
+------------+----------+-------+--------+-------+

我尝试了以下方法,但它looks like you have to return a row, column, and value when using crosstab 所以它不起作用:

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);

有没有办法在使用交叉表时为行指示器使用多个值,还是我必须找到其他方法?

【问题讨论】:

    标签: postgresql crosstab


    【解决方案1】:

    我找到了一个解决方案,尽管它并不理想:将前两个与唯一字符合并,使用 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;
    

    【讨论】:

      猜你喜欢
      • 2017-09-04
      • 1970-01-01
      • 2022-06-16
      • 2011-03-01
      相关资源
      最近更新 更多