Amazon redshift 联合查询红移的性能较差

Amazon redshift 联合查询红移的性能较差,amazon-redshift,Amazon Redshift,我有一个执行得非常糟糕的红移联合查询。查询如下: WITH a1 AS (SELECT revenue_month, SUM(revenue) AS revenue, SUM(cost1) AS cost1, SUM(cost2) AS cost2, SUM(cost3) AS cost3 FROM orders1 GROUP B

我有一个执行得非常糟糕的红移联合查询。查询如下:

WITH a1 AS (SELECT
            revenue_month,
            SUM(revenue) AS revenue,
            SUM(cost1) AS cost1,
            SUM(cost2) AS cost2,
            SUM(cost3) AS cost3
            FROM orders1
            GROUP BY revenue_month),

     a2 AS (SELECT
            revenue_month,
            SUM(revenue) AS revenue,
            SUM(cost1) AS cost1,
            SUM(cost2) AS cost2,
            SUM(cost3) AS cost3
            FROM orders2
            GROUP BY revenue_month),

     b1 AS (SELECT
            revenue_month,
            amount_type,
            SUM(amount) AS amount
            FROM monthly
            GROUP BY revenue_month,amount_type)
             
SELECT 'a1' AS data_set, 'revenue' AS amount_type, a1.revenue AS amount FROM a1 UNION
SELECT 'a1' AS data_set, 'cost1' AS amount_type, a1.cost1 AS amount FROM a1 UNION
SELECT 'a1' AS data_set, 'cost2' AS amount_type, a1.cost2 AS amount FROM a1 UNION
SELECT 'a1' AS data_set, 'cost3' AS amount_type, a1.cost3 AS amount FROM a1 UNION

SELECT 'a2' AS data_set, 'revenue' AS amount_type, a2.revenue AS amount FROM a2 UNION
SELECT 'a2' AS data_set, 'cost1' AS amount_type, a2.cost1 AS amount FROM a2 UNION
SELECT 'a2' AS data_set, 'cost2' AS amount_type, a2.cost2 AS amount FROM a2 UNION
SELECT 'a2' AS data_set, 'cost3' AS amount_type, a2.cost3 AS amount FROM a2 UNION

SELECT 'b1' AS data_set, b1.amount_type, b2.amount FROM b2
WITH
     seq (idx) AS (
         select 'revenue' UNION ALL
         select 'cost1' UNION ALL
         select 'cost2' UNION ALL
         select 'cost3'
     ),
     a1 AS (SELECT
                revenue_month,
                SUM(revenue) AS revenue,
                SUM(cost1) AS cost1,
                SUM(cost2) AS cost2,
                SUM(cost3) AS cost3
            FROM orders1
            GROUP BY revenue_month),

     a2 AS (SELECT
                revenue_month,
                SUM(revenue) AS revenue,
                SUM(cost1) AS cost1,
                SUM(cost2) AS cost2,
                SUM(cost3) AS cost3
            FROM orders2
            GROUP BY revenue_month),

     b1 AS (SELECT
                revenue_month,
                amount_type,
                SUM(amount) AS amount
            FROM monthly
            GROUP BY revenue_month,amount_type)

SELECT
    'a1' AS data_set,
    seq.idx AS amount_type,
    CASE seq.idx
       WHEN 'revenue' THEN a1.revenue
       WHEN 'cost1' THEN a1.cost1
       WHEN 'cost2' THEN a1.cost2
       WHEN 'cost3' THEN a1.cost3
    END AS amount
FROM a1 CROSS JOIN seq

UNION ALL

SELECT
    'a2' AS data_set,
    seq.idx AS amount_type,
    CASE seq.idx
        WHEN 'revenue' THEN a1.revenue
        WHEN 'cost1' THEN a1.cost1
        WHEN 'cost2' THEN a1.cost2
        WHEN 'cost3' THEN a1.cost3
        END AS amount
FROM a2 CROSS JOIN seq

UNION ALL

SELECT 
       'b1' AS data_set, 
       b1.amount_type, 
       b1.amount 
FROM b1
WITH a1 AS (SELECT
            revenue_month,
            SUM(revenue) AS revenue,
            SUM(cost1) AS cost1,
            SUM(cost2) AS cost2,
            SUM(cost3) AS cost3
            FROM orders1
            GROUP BY revenue_month),

     a2 AS (SELECT
            revenue_month,
            SUM(revenue) AS revenue,
            SUM(cost1) AS cost1,
            SUM(cost2) AS cost2,
            SUM(cost3) AS cost3
            FROM orders2
            GROUP BY revenue_month),

     b1 AS (SELECT
            revenue_month,
            SUM(CASE WHEN amount_type = 'revenue' THEN amount ELSE 0 END) AS revenue,
            SUM(CASE WHEN amount_type = 'cost1' THEN amount ELSE 0 END) AS cost1,
            SUM(CASE WHEN amount_type = 'cost2' THEN amount ELSE 0 END) AS cost2,
            SUM(CASE WHEN amount_type = 'cost3' THEN amount ELSE 0 END) AS cost3

            FROM (SELECT
                  revenue_month,
                  amount_type,
                  SUM(amount) AS amount
                  FROM monthly
                  GROUP BY revenue_month,amount_type) AS b0
                  
            GROUP BY revenue_month)

SELECT
ab.data_set,
ab.revenue_month,
seq.amount_type,
CASE seq.amount_type
    WHEN 'revenue' THEN ab.revenue
    WHEN 'cost1' THEN ab.cost1
    WHEN 'cost2' THEN ab.cost2
    WHEN 'cost3' THEN ab.cost3
END AS amount

FROM            
            
(SELECT a1.revenue_month, a1.revenue, a1.cost1, a1.cost2, a1.cost3 FROM a1 UNION ALL
 SELECT a2.revenue_month, a2.revenue, a2.cost1, a2.cost2, a2.cost3 FROM a2 UNION ALL
 SELECT b1.revenue_month, b1.revenue, b1.cost1, b1.cost2, b1.cost3 FROM b1) AS ab
 
 CROSS JOIN (SELECT 'revenue' AS amount_type UNION ALL
             SELECT 'cost1' AS amount_type UNION ALL
             SELECT 'cost2' AS amount_type UNION ALL
             SELECT 'cost3' AS amount_type) AS seq
联合部分的目标是将a1和a2转换为与b1具有相同的结果集模式,并最终具有一个组合数据集

a1和a2子查询单独运行时,完成6000行大约需要60秒,而b1运行500行需要5秒。这些运行时间对我来说是可以接受的,但是,上面的“组合”查询运行了20分钟

我认为获取部分是这个查询花费太多时间的原因。我尝试过使用UNION,但性能并没有提高多少。如果我能在不使用UNION的情况下将a1和a2转换为b1模式,那就太好了,但我还没能做到


任何帮助都将不胜感激。谢谢

您基本上希望取消对
a1
a2
表的锁定

我会这样做:

WITH a1 AS (SELECT
            revenue_month,
            SUM(revenue) AS revenue,
            SUM(cost1) AS cost1,
            SUM(cost2) AS cost2,
            SUM(cost3) AS cost3
            FROM orders1
            GROUP BY revenue_month),

     a2 AS (SELECT
            revenue_month,
            SUM(revenue) AS revenue,
            SUM(cost1) AS cost1,
            SUM(cost2) AS cost2,
            SUM(cost3) AS cost3
            FROM orders2
            GROUP BY revenue_month),

     b1 AS (SELECT
            revenue_month,
            amount_type,
            SUM(amount) AS amount
            FROM monthly
            GROUP BY revenue_month,amount_type)
             
SELECT 'a1' AS data_set, 'revenue' AS amount_type, a1.revenue AS amount FROM a1 UNION
SELECT 'a1' AS data_set, 'cost1' AS amount_type, a1.cost1 AS amount FROM a1 UNION
SELECT 'a1' AS data_set, 'cost2' AS amount_type, a1.cost2 AS amount FROM a1 UNION
SELECT 'a1' AS data_set, 'cost3' AS amount_type, a1.cost3 AS amount FROM a1 UNION

SELECT 'a2' AS data_set, 'revenue' AS amount_type, a2.revenue AS amount FROM a2 UNION
SELECT 'a2' AS data_set, 'cost1' AS amount_type, a2.cost1 AS amount FROM a2 UNION
SELECT 'a2' AS data_set, 'cost2' AS amount_type, a2.cost2 AS amount FROM a2 UNION
SELECT 'a2' AS data_set, 'cost3' AS amount_type, a2.cost3 AS amount FROM a2 UNION

SELECT 'b1' AS data_set, b1.amount_type, b2.amount FROM b2
WITH
     seq (idx) AS (
         select 'revenue' UNION ALL
         select 'cost1' UNION ALL
         select 'cost2' UNION ALL
         select 'cost3'
     ),
     a1 AS (SELECT
                revenue_month,
                SUM(revenue) AS revenue,
                SUM(cost1) AS cost1,
                SUM(cost2) AS cost2,
                SUM(cost3) AS cost3
            FROM orders1
            GROUP BY revenue_month),

     a2 AS (SELECT
                revenue_month,
                SUM(revenue) AS revenue,
                SUM(cost1) AS cost1,
                SUM(cost2) AS cost2,
                SUM(cost3) AS cost3
            FROM orders2
            GROUP BY revenue_month),

     b1 AS (SELECT
                revenue_month,
                amount_type,
                SUM(amount) AS amount
            FROM monthly
            GROUP BY revenue_month,amount_type)

SELECT
    'a1' AS data_set,
    seq.idx AS amount_type,
    CASE seq.idx
       WHEN 'revenue' THEN a1.revenue
       WHEN 'cost1' THEN a1.cost1
       WHEN 'cost2' THEN a1.cost2
       WHEN 'cost3' THEN a1.cost3
    END AS amount
FROM a1 CROSS JOIN seq

UNION ALL

SELECT
    'a2' AS data_set,
    seq.idx AS amount_type,
    CASE seq.idx
        WHEN 'revenue' THEN a1.revenue
        WHEN 'cost1' THEN a1.cost1
        WHEN 'cost2' THEN a1.cost2
        WHEN 'cost3' THEN a1.cost3
        END AS amount
FROM a2 CROSS JOIN seq

UNION ALL

SELECT 
       'b1' AS data_set, 
       b1.amount_type, 
       b1.amount 
FROM b1
WITH a1 AS (SELECT
            revenue_month,
            SUM(revenue) AS revenue,
            SUM(cost1) AS cost1,
            SUM(cost2) AS cost2,
            SUM(cost3) AS cost3
            FROM orders1
            GROUP BY revenue_month),

     a2 AS (SELECT
            revenue_month,
            SUM(revenue) AS revenue,
            SUM(cost1) AS cost1,
            SUM(cost2) AS cost2,
            SUM(cost3) AS cost3
            FROM orders2
            GROUP BY revenue_month),

     b1 AS (SELECT
            revenue_month,
            SUM(CASE WHEN amount_type = 'revenue' THEN amount ELSE 0 END) AS revenue,
            SUM(CASE WHEN amount_type = 'cost1' THEN amount ELSE 0 END) AS cost1,
            SUM(CASE WHEN amount_type = 'cost2' THEN amount ELSE 0 END) AS cost2,
            SUM(CASE WHEN amount_type = 'cost3' THEN amount ELSE 0 END) AS cost3

            FROM (SELECT
                  revenue_month,
                  amount_type,
                  SUM(amount) AS amount
                  FROM monthly
                  GROUP BY revenue_month,amount_type) AS b0
                  
            GROUP BY revenue_month)

SELECT
ab.data_set,
ab.revenue_month,
seq.amount_type,
CASE seq.amount_type
    WHEN 'revenue' THEN ab.revenue
    WHEN 'cost1' THEN ab.cost1
    WHEN 'cost2' THEN ab.cost2
    WHEN 'cost3' THEN ab.cost3
END AS amount

FROM            
            
(SELECT a1.revenue_month, a1.revenue, a1.cost1, a1.cost2, a1.cost3 FROM a1 UNION ALL
 SELECT a2.revenue_month, a2.revenue, a2.cost1, a2.cost2, a2.cost3 FROM a2 UNION ALL
 SELECT b1.revenue_month, b1.revenue, b1.cost1, b1.cost2, b1.cost3 FROM b1) AS ab
 
 CROSS JOIN (SELECT 'revenue' AS amount_type UNION ALL
             SELECT 'cost1' AS amount_type UNION ALL
             SELECT 'cost2' AS amount_type UNION ALL
             SELECT 'cost3' AS amount_type) AS seq

您基本上希望取消打印
a1
a2

我会这样做:

WITH a1 AS (SELECT
            revenue_month,
            SUM(revenue) AS revenue,
            SUM(cost1) AS cost1,
            SUM(cost2) AS cost2,
            SUM(cost3) AS cost3
            FROM orders1
            GROUP BY revenue_month),

     a2 AS (SELECT
            revenue_month,
            SUM(revenue) AS revenue,
            SUM(cost1) AS cost1,
            SUM(cost2) AS cost2,
            SUM(cost3) AS cost3
            FROM orders2
            GROUP BY revenue_month),

     b1 AS (SELECT
            revenue_month,
            amount_type,
            SUM(amount) AS amount
            FROM monthly
            GROUP BY revenue_month,amount_type)
             
SELECT 'a1' AS data_set, 'revenue' AS amount_type, a1.revenue AS amount FROM a1 UNION
SELECT 'a1' AS data_set, 'cost1' AS amount_type, a1.cost1 AS amount FROM a1 UNION
SELECT 'a1' AS data_set, 'cost2' AS amount_type, a1.cost2 AS amount FROM a1 UNION
SELECT 'a1' AS data_set, 'cost3' AS amount_type, a1.cost3 AS amount FROM a1 UNION

SELECT 'a2' AS data_set, 'revenue' AS amount_type, a2.revenue AS amount FROM a2 UNION
SELECT 'a2' AS data_set, 'cost1' AS amount_type, a2.cost1 AS amount FROM a2 UNION
SELECT 'a2' AS data_set, 'cost2' AS amount_type, a2.cost2 AS amount FROM a2 UNION
SELECT 'a2' AS data_set, 'cost3' AS amount_type, a2.cost3 AS amount FROM a2 UNION

SELECT 'b1' AS data_set, b1.amount_type, b2.amount FROM b2
WITH
     seq (idx) AS (
         select 'revenue' UNION ALL
         select 'cost1' UNION ALL
         select 'cost2' UNION ALL
         select 'cost3'
     ),
     a1 AS (SELECT
                revenue_month,
                SUM(revenue) AS revenue,
                SUM(cost1) AS cost1,
                SUM(cost2) AS cost2,
                SUM(cost3) AS cost3
            FROM orders1
            GROUP BY revenue_month),

     a2 AS (SELECT
                revenue_month,
                SUM(revenue) AS revenue,
                SUM(cost1) AS cost1,
                SUM(cost2) AS cost2,
                SUM(cost3) AS cost3
            FROM orders2
            GROUP BY revenue_month),

     b1 AS (SELECT
                revenue_month,
                amount_type,
                SUM(amount) AS amount
            FROM monthly
            GROUP BY revenue_month,amount_type)

SELECT
    'a1' AS data_set,
    seq.idx AS amount_type,
    CASE seq.idx
       WHEN 'revenue' THEN a1.revenue
       WHEN 'cost1' THEN a1.cost1
       WHEN 'cost2' THEN a1.cost2
       WHEN 'cost3' THEN a1.cost3
    END AS amount
FROM a1 CROSS JOIN seq

UNION ALL

SELECT
    'a2' AS data_set,
    seq.idx AS amount_type,
    CASE seq.idx
        WHEN 'revenue' THEN a1.revenue
        WHEN 'cost1' THEN a1.cost1
        WHEN 'cost2' THEN a1.cost2
        WHEN 'cost3' THEN a1.cost3
        END AS amount
FROM a2 CROSS JOIN seq

UNION ALL

SELECT 
       'b1' AS data_set, 
       b1.amount_type, 
       b1.amount 
FROM b1
WITH a1 AS (SELECT
            revenue_month,
            SUM(revenue) AS revenue,
            SUM(cost1) AS cost1,
            SUM(cost2) AS cost2,
            SUM(cost3) AS cost3
            FROM orders1
            GROUP BY revenue_month),

     a2 AS (SELECT
            revenue_month,
            SUM(revenue) AS revenue,
            SUM(cost1) AS cost1,
            SUM(cost2) AS cost2,
            SUM(cost3) AS cost3
            FROM orders2
            GROUP BY revenue_month),

     b1 AS (SELECT
            revenue_month,
            SUM(CASE WHEN amount_type = 'revenue' THEN amount ELSE 0 END) AS revenue,
            SUM(CASE WHEN amount_type = 'cost1' THEN amount ELSE 0 END) AS cost1,
            SUM(CASE WHEN amount_type = 'cost2' THEN amount ELSE 0 END) AS cost2,
            SUM(CASE WHEN amount_type = 'cost3' THEN amount ELSE 0 END) AS cost3

            FROM (SELECT
                  revenue_month,
                  amount_type,
                  SUM(amount) AS amount
                  FROM monthly
                  GROUP BY revenue_month,amount_type) AS b0
                  
            GROUP BY revenue_month)

SELECT
ab.data_set,
ab.revenue_month,
seq.amount_type,
CASE seq.amount_type
    WHEN 'revenue' THEN ab.revenue
    WHEN 'cost1' THEN ab.cost1
    WHEN 'cost2' THEN ab.cost2
    WHEN 'cost3' THEN ab.cost3
END AS amount

FROM            
            
(SELECT a1.revenue_month, a1.revenue, a1.cost1, a1.cost2, a1.cost3 FROM a1 UNION ALL
 SELECT a2.revenue_month, a2.revenue, a2.cost1, a2.cost2, a2.cost3 FROM a2 UNION ALL
 SELECT b1.revenue_month, b1.revenue, b1.cost1, b1.cost2, b1.cost3 FROM b1) AS ab
 
 CROSS JOIN (SELECT 'revenue' AS amount_type UNION ALL
             SELECT 'cost1' AS amount_type UNION ALL
             SELECT 'cost2' AS amount_type UNION ALL
             SELECT 'cost3' AS amount_type) AS seq

感谢@botchniaque在这方面的帮助。您的
交叉连接建议解决了此问题。尽管红移无法读取,但该查询模式还是有些问题。对我有效的最后一个查询是这样的:

WITH a1 AS (SELECT
            revenue_month,
            SUM(revenue) AS revenue,
            SUM(cost1) AS cost1,
            SUM(cost2) AS cost2,
            SUM(cost3) AS cost3
            FROM orders1
            GROUP BY revenue_month),

     a2 AS (SELECT
            revenue_month,
            SUM(revenue) AS revenue,
            SUM(cost1) AS cost1,
            SUM(cost2) AS cost2,
            SUM(cost3) AS cost3
            FROM orders2
            GROUP BY revenue_month),

     b1 AS (SELECT
            revenue_month,
            amount_type,
            SUM(amount) AS amount
            FROM monthly
            GROUP BY revenue_month,amount_type)
             
SELECT 'a1' AS data_set, 'revenue' AS amount_type, a1.revenue AS amount FROM a1 UNION
SELECT 'a1' AS data_set, 'cost1' AS amount_type, a1.cost1 AS amount FROM a1 UNION
SELECT 'a1' AS data_set, 'cost2' AS amount_type, a1.cost2 AS amount FROM a1 UNION
SELECT 'a1' AS data_set, 'cost3' AS amount_type, a1.cost3 AS amount FROM a1 UNION

SELECT 'a2' AS data_set, 'revenue' AS amount_type, a2.revenue AS amount FROM a2 UNION
SELECT 'a2' AS data_set, 'cost1' AS amount_type, a2.cost1 AS amount FROM a2 UNION
SELECT 'a2' AS data_set, 'cost2' AS amount_type, a2.cost2 AS amount FROM a2 UNION
SELECT 'a2' AS data_set, 'cost3' AS amount_type, a2.cost3 AS amount FROM a2 UNION

SELECT 'b1' AS data_set, b1.amount_type, b2.amount FROM b2
WITH
     seq (idx) AS (
         select 'revenue' UNION ALL
         select 'cost1' UNION ALL
         select 'cost2' UNION ALL
         select 'cost3'
     ),
     a1 AS (SELECT
                revenue_month,
                SUM(revenue) AS revenue,
                SUM(cost1) AS cost1,
                SUM(cost2) AS cost2,
                SUM(cost3) AS cost3
            FROM orders1
            GROUP BY revenue_month),

     a2 AS (SELECT
                revenue_month,
                SUM(revenue) AS revenue,
                SUM(cost1) AS cost1,
                SUM(cost2) AS cost2,
                SUM(cost3) AS cost3
            FROM orders2
            GROUP BY revenue_month),

     b1 AS (SELECT
                revenue_month,
                amount_type,
                SUM(amount) AS amount
            FROM monthly
            GROUP BY revenue_month,amount_type)

SELECT
    'a1' AS data_set,
    seq.idx AS amount_type,
    CASE seq.idx
       WHEN 'revenue' THEN a1.revenue
       WHEN 'cost1' THEN a1.cost1
       WHEN 'cost2' THEN a1.cost2
       WHEN 'cost3' THEN a1.cost3
    END AS amount
FROM a1 CROSS JOIN seq

UNION ALL

SELECT
    'a2' AS data_set,
    seq.idx AS amount_type,
    CASE seq.idx
        WHEN 'revenue' THEN a1.revenue
        WHEN 'cost1' THEN a1.cost1
        WHEN 'cost2' THEN a1.cost2
        WHEN 'cost3' THEN a1.cost3
        END AS amount
FROM a2 CROSS JOIN seq

UNION ALL

SELECT 
       'b1' AS data_set, 
       b1.amount_type, 
       b1.amount 
FROM b1
WITH a1 AS (SELECT
            revenue_month,
            SUM(revenue) AS revenue,
            SUM(cost1) AS cost1,
            SUM(cost2) AS cost2,
            SUM(cost3) AS cost3
            FROM orders1
            GROUP BY revenue_month),

     a2 AS (SELECT
            revenue_month,
            SUM(revenue) AS revenue,
            SUM(cost1) AS cost1,
            SUM(cost2) AS cost2,
            SUM(cost3) AS cost3
            FROM orders2
            GROUP BY revenue_month),

     b1 AS (SELECT
            revenue_month,
            SUM(CASE WHEN amount_type = 'revenue' THEN amount ELSE 0 END) AS revenue,
            SUM(CASE WHEN amount_type = 'cost1' THEN amount ELSE 0 END) AS cost1,
            SUM(CASE WHEN amount_type = 'cost2' THEN amount ELSE 0 END) AS cost2,
            SUM(CASE WHEN amount_type = 'cost3' THEN amount ELSE 0 END) AS cost3

            FROM (SELECT
                  revenue_month,
                  amount_type,
                  SUM(amount) AS amount
                  FROM monthly
                  GROUP BY revenue_month,amount_type) AS b0
                  
            GROUP BY revenue_month)

SELECT
ab.data_set,
ab.revenue_month,
seq.amount_type,
CASE seq.amount_type
    WHEN 'revenue' THEN ab.revenue
    WHEN 'cost1' THEN ab.cost1
    WHEN 'cost2' THEN ab.cost2
    WHEN 'cost3' THEN ab.cost3
END AS amount

FROM            
            
(SELECT a1.revenue_month, a1.revenue, a1.cost1, a1.cost2, a1.cost3 FROM a1 UNION ALL
 SELECT a2.revenue_month, a2.revenue, a2.cost1, a2.cost2, a2.cost3 FROM a2 UNION ALL
 SELECT b1.revenue_month, b1.revenue, b1.cost1, b1.cost2, b1.cost3 FROM b1) AS ab
 
 CROSS JOIN (SELECT 'revenue' AS amount_type UNION ALL
             SELECT 'cost1' AS amount_type UNION ALL
             SELECT 'cost2' AS amount_type UNION ALL
             SELECT 'cost3' AS amount_type) AS seq

基本上,它首先以
b1
为轴心,以具有与
a1
a2
相同的模式。然后将所有三个数据集与
UNION
合并,得到
ab
。最后,使用交叉连接取消组合数据集的IVOTS,谢谢@botchniaque在这方面的帮助。您的
交叉连接建议解决了此问题。尽管红移无法读取,但该查询模式还是有些问题。对我有效的最后一个查询是这样的:

WITH a1 AS (SELECT
            revenue_month,
            SUM(revenue) AS revenue,
            SUM(cost1) AS cost1,
            SUM(cost2) AS cost2,
            SUM(cost3) AS cost3
            FROM orders1
            GROUP BY revenue_month),

     a2 AS (SELECT
            revenue_month,
            SUM(revenue) AS revenue,
            SUM(cost1) AS cost1,
            SUM(cost2) AS cost2,
            SUM(cost3) AS cost3
            FROM orders2
            GROUP BY revenue_month),

     b1 AS (SELECT
            revenue_month,
            amount_type,
            SUM(amount) AS amount
            FROM monthly
            GROUP BY revenue_month,amount_type)
             
SELECT 'a1' AS data_set, 'revenue' AS amount_type, a1.revenue AS amount FROM a1 UNION
SELECT 'a1' AS data_set, 'cost1' AS amount_type, a1.cost1 AS amount FROM a1 UNION
SELECT 'a1' AS data_set, 'cost2' AS amount_type, a1.cost2 AS amount FROM a1 UNION
SELECT 'a1' AS data_set, 'cost3' AS amount_type, a1.cost3 AS amount FROM a1 UNION

SELECT 'a2' AS data_set, 'revenue' AS amount_type, a2.revenue AS amount FROM a2 UNION
SELECT 'a2' AS data_set, 'cost1' AS amount_type, a2.cost1 AS amount FROM a2 UNION
SELECT 'a2' AS data_set, 'cost2' AS amount_type, a2.cost2 AS amount FROM a2 UNION
SELECT 'a2' AS data_set, 'cost3' AS amount_type, a2.cost3 AS amount FROM a2 UNION

SELECT 'b1' AS data_set, b1.amount_type, b2.amount FROM b2
WITH
     seq (idx) AS (
         select 'revenue' UNION ALL
         select 'cost1' UNION ALL
         select 'cost2' UNION ALL
         select 'cost3'
     ),
     a1 AS (SELECT
                revenue_month,
                SUM(revenue) AS revenue,
                SUM(cost1) AS cost1,
                SUM(cost2) AS cost2,
                SUM(cost3) AS cost3
            FROM orders1
            GROUP BY revenue_month),

     a2 AS (SELECT
                revenue_month,
                SUM(revenue) AS revenue,
                SUM(cost1) AS cost1,
                SUM(cost2) AS cost2,
                SUM(cost3) AS cost3
            FROM orders2
            GROUP BY revenue_month),

     b1 AS (SELECT
                revenue_month,
                amount_type,
                SUM(amount) AS amount
            FROM monthly
            GROUP BY revenue_month,amount_type)

SELECT
    'a1' AS data_set,
    seq.idx AS amount_type,
    CASE seq.idx
       WHEN 'revenue' THEN a1.revenue
       WHEN 'cost1' THEN a1.cost1
       WHEN 'cost2' THEN a1.cost2
       WHEN 'cost3' THEN a1.cost3
    END AS amount
FROM a1 CROSS JOIN seq

UNION ALL

SELECT
    'a2' AS data_set,
    seq.idx AS amount_type,
    CASE seq.idx
        WHEN 'revenue' THEN a1.revenue
        WHEN 'cost1' THEN a1.cost1
        WHEN 'cost2' THEN a1.cost2
        WHEN 'cost3' THEN a1.cost3
        END AS amount
FROM a2 CROSS JOIN seq

UNION ALL

SELECT 
       'b1' AS data_set, 
       b1.amount_type, 
       b1.amount 
FROM b1
WITH a1 AS (SELECT
            revenue_month,
            SUM(revenue) AS revenue,
            SUM(cost1) AS cost1,
            SUM(cost2) AS cost2,
            SUM(cost3) AS cost3
            FROM orders1
            GROUP BY revenue_month),

     a2 AS (SELECT
            revenue_month,
            SUM(revenue) AS revenue,
            SUM(cost1) AS cost1,
            SUM(cost2) AS cost2,
            SUM(cost3) AS cost3
            FROM orders2
            GROUP BY revenue_month),

     b1 AS (SELECT
            revenue_month,
            SUM(CASE WHEN amount_type = 'revenue' THEN amount ELSE 0 END) AS revenue,
            SUM(CASE WHEN amount_type = 'cost1' THEN amount ELSE 0 END) AS cost1,
            SUM(CASE WHEN amount_type = 'cost2' THEN amount ELSE 0 END) AS cost2,
            SUM(CASE WHEN amount_type = 'cost3' THEN amount ELSE 0 END) AS cost3

            FROM (SELECT
                  revenue_month,
                  amount_type,
                  SUM(amount) AS amount
                  FROM monthly
                  GROUP BY revenue_month,amount_type) AS b0
                  
            GROUP BY revenue_month)

SELECT
ab.data_set,
ab.revenue_month,
seq.amount_type,
CASE seq.amount_type
    WHEN 'revenue' THEN ab.revenue
    WHEN 'cost1' THEN ab.cost1
    WHEN 'cost2' THEN ab.cost2
    WHEN 'cost3' THEN ab.cost3
END AS amount

FROM            
            
(SELECT a1.revenue_month, a1.revenue, a1.cost1, a1.cost2, a1.cost3 FROM a1 UNION ALL
 SELECT a2.revenue_month, a2.revenue, a2.cost1, a2.cost2, a2.cost3 FROM a2 UNION ALL
 SELECT b1.revenue_month, b1.revenue, b1.cost1, b1.cost2, b1.cost3 FROM b1) AS ab
 
 CROSS JOIN (SELECT 'revenue' AS amount_type UNION ALL
             SELECT 'cost1' AS amount_type UNION ALL
             SELECT 'cost2' AS amount_type UNION ALL
             SELECT 'cost3' AS amount_type) AS seq

基本上,它首先以
b1
为轴心,以具有与
a1
a2
相同的模式。然后将所有三个数据集与
UNION
合并,得到
ab
。最后,使用交叉连接将组合的数据集解压出来

感谢man@botchniaque的快速回答。我已经测试过交叉连接方法正确地转换a1和a2。但是,当使用a1、a2和b1的UNION ALL部分运行最终查询时,会抛出一个错误
XX000:由于内部错误,不支持这种类型的相关子查询模式。我已经检查了这个,但是这个查询模式不包括在这个列表中。知道是什么原因吗?你使用的确切查询是什么?您是否直接使用了我的示例?也许将
a1
a2
的解压移动到他们自己的cte(
,其中a1_解压为(…),a2_解压为(…)
)会有所帮助?我被你得到的错误弄糊涂了,因为那里没有子查询。嘿,谢谢你的及时回复!非常感谢。实际上,我也尝试了你建议的方法——将“取消激励”转移到他们自己的CTE中,但奇怪的是,同样的错误被抛出。当交叉连接和联合都集成在查询中时,redshift读取它的方式存在一些问题,即它总是失败,并出现相同的错误,但在运行单个CTE时没有问题。然而,在玩了一整天之后,对我有效的方法是将
b1
转换为
a1
a2
的结果模式,对三个CTE进行
合并,然后最后进行
交叉连接
,以取消Pivotthanks man@botchniaque以获得快速答案。我已经测试过交叉连接方法正确地转换a1和a2。但是,当使用a1、a2和b1的UNION ALL部分运行最终查询时,会抛出一个错误
XX000:由于内部错误,不支持这种类型的相关子查询模式。我已经检查了这个,但是这个查询模式不包括在这个列表中。知道是什么原因吗?你使用的确切查询是什么?您是否直接使用了我的示例?也许将
a1
a2
的解压移动到他们自己的cte(
,其中a1_解压为(…),a2_解压为(…)
)会有所帮助?我被你得到的错误弄糊涂了,因为那里没有子查询。嘿,谢谢你的及时回复!非常感谢。实际上,我也尝试了你建议的方法——将“取消激励”转移到他们自己的CTE中,但奇怪的是,同样的错误被抛出。当交叉连接和联合都集成在查询中时,redshift读取它的方式存在一些问题,即它总是失败,并出现相同的错误,但在运行单个CTE时没有问题。然而,在玩了一整天之后,对我有效的方法是将
b1
转换为
a1
a2
的结果模式,对三个CTE进行
联合
,然后最后将
交叉连接
取消PIVOT