正在使用Oracle 12c R1 db并拥有包含示例数据的示例视图,如下所示:
查看名称: CUST_HOTEL_VIEW
+----------------+---------------+---------------+
| Customer | Hotel | Booked Status |
+----------------+---------------+---------------+
| John Smith | Beverly Hills | Booked |
| John Smith | Royal Palms | |
| Marilyn Lawson | Beverly Hills | |
| John Smith | Ritz-Carlton | |
| Marilyn Lawson | Royal Palms | |
| Sarah Elliot | Royal Palms | |
| Sarah Elliot | Ritz-Carlton | Booked |
| Sarah Elliot | Royal Palms | Booked |
+----------------+---------------+---------------+
根据上述数据,我试图通过Row Grand Total,Column Grand Total和每位客户预订的酒店数量来获得枢轴输出:
+----------------+-------------+---------------+--------------+-------------+----------+
| Customer | Royal Palms | Beverly Hills | Ritz-Carlton | Grand Total | # Booked |
+----------------+-------------+---------------+--------------+-------------+----------+
| John Smith | 1 | 1 | 1 | 3 | 1 |
| Marilyn Lawson | 1 | 1 | | 2 | - |
| Sarah Elliot | 2 | | 1 | 3 | 2 |
| Grand Total | 4 | 2 | 2 | 8 | 3 |
+----------------+-------------+---------------+--------------+-------------+----------+
我在下面尝试查询以生成数据透视数据
SELECT * FROM
(
SELECT CUSTOMER, HOTEL
FROM CUST_HOTEL_VIEW
)
PIVOT
(
COUNT(HOTEL)
FOR HOTEL IN ('Royal Palms' as "Royal Palms",'Beverly Hills' as "Beverly Hills",'Ritz-Carlton' as "Ritz-Carlton")
)
ORDER BY CUSTOMER
我想知道:
1.如何包括Row Grand Total
2.如何包括列总计
3.如何包括预订酒店数量和
3.是否可以在PIVOT FOR HOTEL IN子句中编写子查询。 (我试过子查询但得到错误)
我很感激任何帮助。
谢谢,
Richa
答案 0 :(得分:3)
只需使用条件聚合:
SELECT COALESCE(customer, 'Grand Total') as customer,
SUM(CASE WHEN Hotel = 'Royal Palms' THEN 1 ELSE 0 END) as "Royal Palms",
SUM(CASE WHEN Hotel = 'Beverly Hills' THEN 1 ELSE 0 END) as "Beverly Hills",
SUM(CASE WHEN Hotel = 'Ritz-Carlton' THEN 1 ELSE 0 END) as "Ritz-Carlton" ,
COUNT(*) as "Grand Total",
COUNT(Booked_Status) as "Num Booked"
FROM CUST_HOTEL_VIEW
GROUP BY ROLLUP(CUSTOMER)
ORDER BY CUSTOMER;
条件聚合比pivot
更灵活。就个人而言,我认为pivot
语法没有理由:它做得很好,但不像传统SQL语句那样构建块。
ROLLUP()
也很有帮助。您也可以使用:
GROUP BY GROUPING SETS ( (CUSTOMER), () )
答案 1 :(得分:1)
可能有一个更简单的解决方案,但这应该可以帮助您入门 -
WITH A AS (
SELECT
*
FROM
(
SELECT
CUSTOMER,
HOTEL,
BOOKED_STATUS
FROM
TABLE1
)
PIVOT ( COUNT ( HOTEL )
FOR HOTEL
IN ( 'ROYAL PALMS' AS "ROYAL PALMS",'BEVERLY HILLS' AS "BEVERLY HILLS",'RITZ-CARLTON' AS "RITZ-CARLTON" )
)
),B AS (
SELECT
CUSTOMER,
"ROYAL PALMS",
"BEVERLY HILLS",
"RITZ-CARLTON",
SUM("ROYAL PALMS" + "BEVERLY HILLS" + "RITZ-CARLTON") AS "GRAND TOTAL"
FROM
A
GROUP BY
CUSTOMER,
"ROYAL PALMS",
"BEVERLY HILLS",
"RITZ-CARLTON"
),C AS (
SELECT
CUSTOMER,
SUM("ROYAL PALMS" + "BEVERLY HILLS" + "RITZ-CARLTON") AS NBOOK
FROM
A
WHERE
BOOKED_STATUS IS NOT NULL
GROUP BY
CUSTOMER
),D AS (
SELECT
B.CUSTOMER,
SUM("ROYAL PALMS") AS "ROYAL PALMS",
SUM("BEVERLY HILLS") AS "BEVERLY HILLS",
SUM("RITZ-CARLTON") AS "RITZ-CARLTON",
SUM("GRAND TOTAL") AS "GRAND TOTAL",
NVL(C.NBOOK,0) AS NBOOK
FROM
B,
C
WHERE
B.CUSTOMER = C.CUSTOMER (+)
GROUP BY
B.CUSTOMER,
NVL(C.NBOOK,0)
) SELECT
*
FROM
D
UNION
SELECT
'GRAND TOTAL' AS CUSTOMER,
SUM("ROYAL PALMS"),
SUM("BEVERLY HILLS"),
SUM("RITZ-CARLTON"),
SUM("GRAND TOTAL") AS "GRAND TOTAL",
SUM(NBOOK) AS NBOOK
FROM
D
ORDER BY 5,1;
输出 -
"CUSTOMER","ROYAL PALMS","BEVERLY HILLS","RITZ-CARLTON","GRAND TOTAL","NBOOK"
"MARILYN LAWSON",1,1,0,2,0
"JOHN SMITH",1,1,1,3,1
"SARAH ELLIOT",2,0,1,3,2
"GRAND TOTAL",4,2,2,8,3
答案 2 :(得分:1)
试试这个:
1)要包含行总数union
,可以使用
2)要在第一个表(p1)中使用列总计sum
函数:使用sum函数编写的相同代码
3)要包括预订酒店数量,需要another pivot
,这是第二张表(第2页)
步骤1:与客户,不同酒店及其总计(列总数)制作表格p1
create table p1 as
SELECT customer,RoyalPalms,BeverlyHills,RitzCarlton,sum(RoyalPalms + BeverlyHills + RitzCarlton) as GrandTotal FROM
(
SELECT CUSTOMER, HOTEL
FROM CUST
)
PIVOT
( COUNT(HOTEL)
FOR HOTEL IN ('Royal Palms' as RoyalPalms,'Beverly Hills' as BeverlyHills,
'Ritz-Carlton' as RitzCarlton) )
group by customer,RoyalPalms,BeverlyHills,RitzCarlton
order by customer;
步骤2:与客户和预订酒店制作表格p2
create table p2 as
SELECT * FROM
(
SELECT customer,booked_status
FROM cust
)
pivot
( count(booked_status)
for booked_status in ('Booked' as Booked));
第3步:加入表格p1和p2
步骤4:对于行总计,将第3步中创建的表的并集与汇总函数计算的行总数
(SELECT a.*,b.booked
from p1 a
left join
p2 b
on a.customer = b.customer)
union all
SELECT 'GrandTotal', Sum(RoyalPalms),sum(BeverlyHills),sum(RitzCarlton),
sum(GrandTotal),sum(booked) From test;
<强>输出:强>
+----------------+-------------+---------------+--------------+-------------+----------+
| Customer | Royal Palms | Beverly Hills | Ritz-Carlton | Grand Total | # Booked |
+----------------+-------------+---------------+--------------+-------------+----------+
| John Smith | 1 | 1 | 1 | 3 | 1 |
| Marilyn Lawson | 1 | 1 | | 2 | - |
| Sarah Elliot | 2 | | 1 | 3 | 2 |
| Grand Total | 4 | 2 | 2 | 8 | 3 |
+----------------+-------------+---------------+--------------+-------------+----------+
如果需要进一步查询/解释,请告诉我。