Redshift не поддерживает функции rollup(), grouping().

Попытка преобразовать сценарии Teradata bteq SQL в красное смещение SQL. Моя текущая версия Postgres с красным смещением — 8.0.2, версия с красным смещением — 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.


person pavan kumar    schedule 27.11.2017    source источник
comment
пожалуйста, предоставьте пример teradata sql, а также то, что вы пробовали до сих пор в красном смещении,   -  person Jon Scott    schedule 27.11.2017
comment
@JonScott Пытаюсь преобразовать простые функции Rollup() и grouping() в Redshift, но не смог.   -  person pavan kumar    schedule 27.11.2017
comment
Чтобы сделать это в Redshift или любой другой базе данных, которая не поддерживает свертки, вам нужно запустить каждую группу по отдельности, а затем объединить результаты. это можно сделать в 1 select с помощью cte   -  person Jon Scott    schedule 27.11.2017
comment
Не могли бы вы помочь мне с примером для приведенного выше запроса Sql   -  person pavan kumar    schedule 28.11.2017
comment
Я использовал следующую ссылку писать SQL Rollup, группирующие запросы в Redshift. Это сработало.   -  person pavan kumar    schedule 29.12.2017


Ответы (2)


Если вы используете метод UNION, на который указывали другие, вы будете сканировать базовую таблицу несколько раз.

Если GROUP на тонком уровне действительно приводит к значительному уменьшению размера данных, лучшим решением может быть:

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
person dsz    schedule 19.04.2018

Реализовать ROLLUP вручную

Поскольку Redshift в настоящее время не распознает предложение ROLLUP, вы должны усложнить реализацию этой техники группировки.

ОБЪЕДИНЕНИЕ с 1 аргументом

С ROLLUP Ex. 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

ROLLUP с 2 аргументами

С ROLLUP Ex. 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
person ePi272314    schedule 05.07.2019