8

Tôi có một Truy vấn Máy chủ Sql đang sử dụng mệnh đề ROLLUP trong khi nhóm. Tôi muốn có một truy vấn tương đương trong Postgres. Truy vấn trong SQL Server là:PostgreSQL tương đương với SQL Server GROUP BY VỚI ROLLUP

SELECT (CASE WHEN acnt_dba_name Is Null THEN 'Total' ELSE acnt_dba_name END) as account, 
     (CASE WHEN evt_name Is Null THEN '' ELSE evt_name END) as event, 
     COUNT(CASE reg_is_complete WHEN true THEN 1 ELSE Null END) as regsComplete, 
     COUNT(CASE WHEN reg_frn_pro_id > 0 AND reg_is_complete = false THEN 1 ELSE Null END) as regsInComplete, 
     COUNT(CASE WHEN reg_frn_pro_id > 0 THEN Null ELSE 1 END) as regsClicks 
FROM  registrations_view 
LEFT JOIN events ON (evt_id = reg_frn_evt_id) 
LEFT JOIN accounts ON (acnt_id = evt_frn_acnt_id) 
WHERE reg_date_created < #CreateODBCDate(url.endDate)# 
AND reg_date_created > #CreateODBCDate(url.startDate)# 
AND reg_is_active = true  -- only active regs 
AND reg_is_test = false  -- only live registrations 
-- AND reg_is_denied = false   -- exclude denied reg statuses (include these for now RWB 8/7/2) 
GROUP BY rollup(acnt_dba_name, evt_name) 
-- Sort with Nulls at the bottom 
ORDER BY acnt_dba_name, evt_name 

Trả lời

16
with detail as (
    select 
     acnt_dba_name as account, 
     evt_name as event, 
     count(case reg_is_complete when true then 1 else null end) as regscomplete, 
     count(case when reg_frn_pro_id > 0 and reg_is_complete = false then 1 else null end) as regsincomplete, 
     count(case when reg_frn_pro_id > 0 then null else 1 end) as regsclicks 
    from 
     registrations_view 
     left join 
     events on evt_id = reg_frn_evt_id 
     left join 
     accounts on acnt_id = evt_frn_acnt_id 
    where 
     reg_date_created < #CreateODBCDate(url.endDate)# 
     AND reg_date_created > #CreateODBCDate(url.startDate)# 
     and reg_is_active = true  -- only active regs 
     and reg_is_test = false  -- only live registrations 
    group by acnt_dba_name, evt_name 
), account as (
    select 
     account, 
     '' as event, 
     sum(regscomplete) as regscomplete, 
     sum(regsimcomplete) as regsincomplete, 
     sum(regsclicks) as regsclicks 
    from detail 
    group by account 
), total as (
    select 
     'Total' as account, 
     '' as event, 
     sum(regsComplete) as regsComplete, 
     sum(regsImComplete) as regsInComplete, 
     sum(regsClicks) as regsClicks 
    from account 
) 
select * from detail 
union 
select * from account 
union 
select * from total 
order by account, event 
+0

cảm ơn và công việc tuyệt vời bởi bạn –

+2

Bạn nên sử dụng 'UNION ALL' thay vì 'UNION', do đó, DB sẽ không phải cố gắng loại bỏ các bản sao. –

8

Đây là một câu trả lời chung để tương đương với cuộn lên trong PostgreSQL.

Cho một bảng t:

create table t (l1 char(1), l2 char(1), i integer); 
insert into t (l1, l2, i) values 
('A', 'X', 1), 
('A', 'Y', 2), 
('B', 'X', 3), 
('B', 'Y', 4); 

Và đây truy vấn SQL Server: SQL Fiddle

select l1, l2, sum(i) total 
from t 
group by rollup(l1, l2) 

Đây là cách để làm điều đó trong PostgreSQL: SQL Fiddle

Tạo CTEs tập hợp bắt đầu từ chi tiết đạt đến cấp cao nhất:

with detail as (
    select l1, l2, sum(i) total 
    from t 
    group by l1, l2 
), l2 as (
    select l1, sum(total) total 
    from detail 
    group by l1 
), l1 as (
    select sum(total) total 
    from l2 
) 

Lưu ý rằng để thực hiện cấp độ tiếp theo tổng hợp từ mức giảm trước đó.

Với điều đó được thực hiện chỉ công đoàn các CTEs tạo nhãn thích hợp:

select l1, l2, total 
from detail 
union 
select l1, 'Total', total 
from l2 
union 
select 'Total', '', total 
from l1 
order by l1, l2