【问题标题】:Redshift does not support rollup(), grouping() functionsRedshift 不支持 rollup()、grouping() 函数
【发布时间】:2018-05-10 11:21:26
【问题描述】:

尝试将 Teradata bteq SQL 脚本转换为 redshift SQL。我目前的 redshift Postgres 版本是 8.0.2,redshift 版本是 1.0.1499。当前版本的 redshift 不支持 rollup()、grouping() 函数。如何克服和解决这种情况。它们的等效红移函数是什么?谁能用一些例子解释一下怎么做?

Teradata SQL 示例-

select 
PRODUCT_ID,CUST_ID, 
GROUPING (PRODUCT_ID), 
GROUPING (CUST_ID), 
row_number over (order by PRODUCT_ID,CUST_ID) AS "ROW_OUTPUT_NUM"
from products 
group by rollup(PRODUCT_ID,CUST_ID);

需要将上面的sql查询转换成Redshift

【问题讨论】:

  • 请提供一些示例 teradata sql 以及您迄今为止在 redshift 中尝试过的内容,
  • @JonScott 尝试将简单的 Rollup() 和 grouping() 函数转换为 Redshift,但没有成功。
  • 要在 redshift 或任何不支持汇总的数据库中执行此操作,您需要单独运行每个组,然后合并结果。这可以使用 cte 在 1 次选择中完成
  • 你能帮我举一个上面的 Sql 查询的例子吗
  • 我用下面的link写了SQL Rollup,Redshift中的分组查询。它奏效了。

标签: sql group-by amazon-redshift rollup


【解决方案1】:

如果您使用其他人指出的 UNION 技术,您将多次扫描基础表。

如果精细级别的 GROUPing 实际上导致数据量显着减少,更好的解决方案可能是:

create temp table summ1 
as
select PRODUCT_ID,CUST_ID, ...
from products 
group by PRODUCT_ID,CUST_ID;

create temp table summ2
as
select PRODUCT_ID,cast(NULL as INT) AS CUST_ID, ...
from products 
group by PRODUCT_ID;

select * from summ1
union all
select * from summ2
union all
select cast(NULL as INT) AS PRODUCT_ID, cast(NULL as INT) AS CUST_ID, ...
from summ2

【讨论】:

    【解决方案2】:

    手动实现 ROLLUP

    一旦 Redshift 当前无法识别 ROLLUP 子句,您就必须实施这种分组技术。

    ROLLUP 1 个参数

    使用 ROLLUP 示例。 PostgreSQL

    SELECT column1, aggregate_function(*)
    FROM some_table
    GROUP BY ROLLUP(column1)
    

    等效实现

    -- First, the same GROUP BY without the ROLLUP
    -- For efficiency, we will reuse this table
    DROP TABLE IF EXISTS tmp_totals;
    CREATE TEMP TABLE tmp_totals AS
      SELECT column1, aggregate_function(*) AS total1
      FROM some_table
      GROUP BY column1;
    
    -- Show the table 'tmp_totals'
    SELECT * FROM tmp_totals
    
    UNION ALL
    
    -- The aggregation of 'tmp_totals'
    SELECT null, aggregate_function(total1) FROM tmp_totals
    
    ORDER BY 1
    

    示例输出

    Country  | Sales
    -------- | -----
    Poland   | 2
    Portugal | 4
    Ukraine  | 3
    null     | 9
    

    带有 2 个参数的 ROLLUP

    使用 ROLLUP 示例。 PostgreSQL

    SELECT column1, column2, aggregate_function(*)
    FROM some_table
    GROUP BY ROLLUP(column1, column2);
    

    等效实现

    -- First, the same GROUP BY without the ROLLUP
    -- For efficiency, we will reuse this table
    DROP TABLE IF EXISTS tmp_totals;
    CREATE TEMP TABLE tmp_totals AS
      SELECT column1, column2, aggregate_function(*) AS total1
      FROM some_table
      GROUP BY column1, column2;
    
    -- Show the table 'tmp_totals'
    SELECT * FROM tmp_totals
    
    UNION ALL
    
    -- The sub-totals of the first category
    SELECT column1, null, sum(total1) FROM tmp_totals GROUP BY column1
    
    UNION ALL
    
    -- The full aggregation of 'tmp_totals'
    SELECT null, null, sum(total1) FROM tmp_totals
    
    ORDER BY 1, 2;
    

    示例输出

    Country  | Segment  | Sales
    -------- | -------- | -----
    Poland   | Premium  | 0
    Poland   | Base     | 2
    Poland   | null     | 2     <- sub total
    Portugal | Premium  | 1
    Portugal | Base     | 3
    Portugal | null     | 4     <- sub total
    Ukraine  | Premium  | 1
    Ukraine  | Base     | 2
    Ukraine  | null     | 3     <- sub total
    null     | null     | 9     <- grand total
    

    【讨论】:

      猜你喜欢
      • 2020-10-09
      • 1970-01-01
      • 2014-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-21
      • 2022-11-19
      相关资源
      最近更新 更多