OCP課程17:SQL之透過分組相關資料產生報告
課程目標:
- ROLLUP
- CUBE
- GROUPING
- GROUPING SETS
1、複習組函式、group by子句及having子句
- group functions 可以位於select lists,order by and having clause
- grouping column隱式升序排序
語法:
例子:使用組函式取平均薪水,薪水標準差,提成總計,最大入職日期
SQL> select avg(salary),stddev(salary),count(commission_pct),max(hire_date)
2 from employees where job_id like 'SA%';
AVG(SALARY) STDDEV(SALARY) COUNT(COMMISSION_PCT) MAX(HIRE_DAT
----------- -------------- --------------------- ------------
8900 2030.64754 35 21-APR-08
例子:檢視每個部門每個職位的薪水合計及人數
SQL> select department_id,job_id,sum(salary),count(employee_id)
2 from employees
3 group by department_id,job_id;
DEPARTMENT_ID JOB_ID SUM(SALARY) COUNT(EMPLOYEE_ID)
------------- ---------- ----------- ------------------
110 AC_ACCOUNT 8300 1
2、ROLLUP運算子
rollup是group by子句的擴充套件,用於產生小計。
語法:
運算規則是從右往左把group by後面的分組欄位整體分組後,再一個一個去掉,剩下的group by,有n個欄位,則會有n+1組結果。
例子:查詢各個部門的薪水小計及整個公司的總薪水
使用集合的方式,需要進行2次查詢
SQL> select department_id,sum(salary) from employees group by department_id
2 union
3 select null,sum(salary) from employees;
DEPARTMENT_ID SUM(SALARY)
------------- -----------
10 10400
741416
13 rows selected.
使用rollup,只需要進行1次查詢
SQL> select department_id,sum(salary) from employees group by rollup(department_id);
DEPARTMENT_ID SUM(SALARY)
------------- -----------
10 10400
741416
13 rows selected.
例子:查詢按部門和職位分組,按部門分組的薪水小計以及公司薪水總計
使用集合的方式,需要進行3次查詢
SQL> select department_id,job_id,sum(salary) from employees group by department_id,job_id
2 union
3 select department_id,null,sum(salary) from employees group by department_id
4 union
5 select null,null,sum(salary) from employees;
DEPARTMENT_ID JOB_ID SUM(SALARY)
------------- ---------- -----------
10 AD_ASST 4400
741416
33 rows selected.
使用rollup,只需要進行1次查詢
SQL> select department_id,job_id,sum(salary) from employees group by rollup(department_id,job_id);
DEPARTMENT_ID JOB_ID SUM(SALARY)
------------- ---------- -----------
SA_REP 7000
741416
33 rows selected.
檢視執行計劃,只進行了1次全部掃描,減少物理I/O
SQL> explain plan for
2 select department_id,job_id,sum(salary) from employees group by rollup(department_id,job_id);
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 1088000809
--------------------------------------------------------------------------------
--
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time
|
--------------------------------------------------------------------------------
--
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 108 | 1728 | 4 (25)| 00:00:01
|
| 1 | SORT GROUP BY ROLLUP| | 108 | 1728 | 4 (25)| 00:00:01
|
| 2 | TABLE ACCESS FULL | EMPLOYEES | 108 | 1728 | 3 (0)| 00:00:01
|
--------------------------------------------------------------------------------
--
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
9 rows selected.
3、CUBE運算子
cube是group by子句的擴充套件,用於產生交叉彙總。
語法:
運算規則是對group by後面的分組欄位所有組合進行聚合,有n個欄位,則會有2^n組結果。
例子:查詢按部門及職位分組,按部門分組及職位分組的薪水小計以及公司薪水總計
使用集合的方式,需要進行4次查詢
SQL> select department_id,job_id,sum(salary) from employees group by department_id,job_id
2 union
3 select department_id,null,sum(salary) from employees group by department_id
4 union
5 select null,job_id,sum(salary) from employees group by job_id
6 union
7 select null,null,sum(salary) from employees;
DEPARTMENT_ID JOB_ID SUM(SALARY)
------------- ---------- -----------
10 AD_ASST 4400
741416
52 rows selected.
使用cube,只需要進行1次查詢
SQL> select department_id,job_id,sum(salary) from employees group by cube(department_id,job_id);
DEPARTMENT_ID JOB_ID SUM(SALARY)
------------- ---------- -----------
741416
110 AC_ACCOUNT 8300
52 rows selected.
4、grouping函式
主要用於區分查詢結果裡面的null是使用ROLLUP或者CUBE產生的還是本來就是null,如果是由ROLLUP或者CUBE產生的,返回1,否則返回0。
語法:
例子:使用grouping函式,確認查詢結果中的null是否是由rollup產生
SQL> select department_id deptid,job_id job,sum(salary),grouping(department_id) grp_detp,grouping(job_id) grp_job
2 from employees where department_id<50
3 group by rollup(department_id,job_id);
DEPTID JOB SUM(SALARY) GRP_DETP GRP_JOB
---------- ---------- ----------- ---------- ----------
10 MK_REP 6000 0 0
10 AD_ASST 4400 0 0
10 10400 0 1
20 MK_MAN 13000 0 0
20 13000 0 1
30 PU_MAN 11000 0 0
30 PU_CLERK 13900 0 0
30 24900 0 1
40 HR_REP 6500 0 0
40 6500 0 1
54800 1 1
11 rows selected.
例子:使用說明文字替換rollup產生的null
SQL> select
2 decode(grouping(department_id),1,(decode(grouping(job_id),1,'total:',department_id)),department_id) as deptid,
3 decode(grouping(job_id),1,(decode(grouping(department_id),1,null,'subtotal:')),job_id),
4 sum(salary)
5 from employees where department_id<60
6 group by rollup(department_id,job_id);
DEPTID DECODE(GRO SUM(SALARY)
---------------------------------------- ---------- -----------
10 MK_REP 6000
10 AD_ASST 4400
10 subtotal: 10400
20 MK_MAN 13000
20 subtotal: 13000
30 PU_MAN 11000
30 PU_CLERK 13900
30 subtotal: 24900
40 HR_REP 6500
40 subtotal: 6500
50 ST_MAN 36400
DEPTID DECODE(GRO SUM(SALARY)
---------------------------------------- ---------- -----------
50 SH_CLERK 64300
50 ST_CLERK 105700
50 subtotal: 206400
total: 261200
15 rows selected.
5、grouping sets
- 在同一個查詢中定義多個分組
- 相當於使用union all拼接起來
- 只需對源表掃描一次,提升效能
例子:計算相同部門相同職務人員的平均薪水以及相同職務相同領導的平均薪水
SQL> select department_id,job_id,manager_id,avg(salary) from employees
2 group by grouping sets((department_id,job_id),(job_id,manager_id));
DEPARTMENT_ID JOB_ID MANAGER_ID AVG(SALARY)
------------- ---------- ---------- -----------
AC_MGR 101 12008
檢視執行計劃,對源表掃描1次後生成比源表小的2個臨時表,後續就對臨時表進行操作。
SQL> explain plan for
2 select department_id,job_id,manager_id,avg(salary) from employees
3 group by grouping sets((department_id,job_id),(job_id,manager_id));
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 52239849
--------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 108 | 4968 | 11 (19)| 00:00:01 |
| 1 | TEMP TABLE TRANSFORMATION | | | | | |
| 2 | LOAD AS SELECT | SYS_TEMP_0FD9D6605_242506 | | | | |
| 3 | TABLE ACCESS FULL | EMPLOYEES | 108 | 2160 | 3 (0)| 00:00:01 |
| 4 | LOAD AS SELECT | SYS_TEMP_0FD9D6606_242506 | | | | |
| 5 | HASH GROUP BY | | 108 | 1836 | 3 (34)| 00:00:01 |
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
| 6 | TABLE ACCESS FULL | SYS_TEMP_0FD9D6605_242506 | 108 | 1836 | 2 (0)| 00:00:01 |
| 7 | LOAD AS SELECT | SYS_TEMP_0FD9D6606_242506 | | | | |
| 8 | HASH GROUP BY | | 108 | 1728 | 3 (34)| 00:00:01 |
| 9 | TABLE ACCESS FULL | SYS_TEMP_0FD9D6605_242506 | 108 | 1728 | 2 (0)| 00:00:01 |
| 10 | VIEW | | 108 | 4968 | 2 (0)| 00:00:01 |
| 11 | TABLE ACCESS FULL | SYS_TEMP_0FD9D6606_242506 | 108 | 1836 | 2 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------------
18 rows selected.
如果不使用grouping sets,使用union all就需要掃描employees2遍
SQL> select department_id,job_id,null,avg(salary) from employees group by department_id,job_id
2 union all
3 select null,job_id,manager_id,avg(salary) from employees group by job_id,manager_id;
DEPARTMENT_ID JOB_ID NULL AVG(SALARY)
------------- ---------- ---------- -----------
110 AC_ACCOUNT 8300
前面講的rollup和cube都可以使用grouping sets來進行組合。
6、複合列
就是將多列使用括號括起來作為1個整體。
例子:查詢按部門、領導和職位分組,按部門分組的薪水小計以及公司薪水總計
SQL> select department_id,job_id,manager_id,sum(salary) from employees
2 group by rollup(department_id,(job_id,manager_id));
DEPARTMENT_ID JOB_ID MANAGER_ID SUM(SALARY)
------------- ---------- ---------- -----------
SA_REP 149 7000
741416
使用grouping sets及複合列與單獨使用group by與union all的對應關係
7、相關習題
(1)View the Exhibit and examine the descriptions of ORDER_ITEMS and ORDERS tables. You want to display the CUSTOMER_ID, PRODUCT_ID, and total (UNIT_PRICE multiplied by QUANTITY) for the order placed. You also want to display the subtotals for a CUSTOMER_ID as well as for a PRODUCT_ID for the last six months. Which SQL statement would you execute to get the desired output?
A.SELECT o.customer_id, oi.product_id, SUM(oi.unit_price*oi.quantity) "Total" FROM order_items oi JOIN orders o ON oi.order_id=o.order_id GROUP BY ROLLUP (o.customer_id,oi.product_id) WHERE MONTHS_BETWEEN(order_date, SYSDATE) <= 6 .
B.SELECT o.customer_id, oi.product_id, SUM(oi.unit_price*oi.quantity) "Total" FROM order_items oi JOIN orders o ON oi.order_id=o.order_id GROUP BY ROLLUP (o.customer_id,oi.product_id) HAVING MONTHS_BETWEEN(order_date, SYSDATE) <= 6 .
C.SELECT o.customer_id, oi.product_id, SUM(oi.unit_price*oi.quantity) "Total" FROM order_items oi JOIN orders o ON oi.order_id=o.order_id GROUP BY ROLLUP (o.customer_id, oi.product_id) WHERE MONTHS_BETWEEN(order_date, SYSDATE) >= 6 .
D.SELECT o.customer_id, oi.product_id, SUM(oi.unit_price*oi.quantity) "Total" FROM order_items oi JOIN orders o ON oi.order_id=o.order_id WHERE MONTHS_BETWEEN(order_date, SYSDATE) <= 6 GROUP BY ROLLUP (o.customer_id, oi.product_id) .
答案:D
(2)In which scenario would you use the ROLLUP operator for expression or columns within a GROUP BY clause?
A.to find the groups forming the subtotal in a row
B.to create group?wise grand totals for the groups specified within a GROUP BY clause
C.to create a grouping for expressions or columns specified within a GROUP BY clause in one direction, from right to left for calculating the subtotals
D.to create a grouping for expressions or columns specified within a GROUP BY clause in all possible directions, which is cross?tabular report for calculating the subtotals
答案:C
(3)Which statement best describes the GROUPING function?
A.It is used to set the order for the groups to be used for calculating the grand totals and subtotals.
B.It is used to form various groups to calculate total and subtotals created using ROLLUP and CUBE operators.
C.It is used to identify if the NULL value in an expression is a stored NULL value or created by ROLLUP or CUBE.
D.It is used to specify the concatenated group expressions to be used for calculating the grand totals andsubtotals.
答案:C
(4)Which statement is true regarding the ROLLUP operator specified in the GROUP BY clause of a SQL statement?
A.It produces only the subtotals for the groups specified in the GROUP BY clause.
B.It produces only the grand totals for the groups specified in the GROUP BY clause.
C.It produces higher-level subtotals, moving from right to left through the list of grouping columns specified in the GROUP BY clause.
D.It produces higher-level subtotals, moving in all the directions through the list of grouping columns specified in the GROUP BY clause.
答案:C
(5)Which two statements are true about the GROUPING function? (Choose two.)
A.It is used to find the groups forming the subtotal in a row.
B.It is used to identify the NULL value in the aggregate functions.
C.It is used to form the group sets involved in generating the totals and subtotals.
D.It can only be used with ROLLUP and CUBE operators specified in the GROUP BY clause.
答案:AD
(6)View the Exhibit and examine the descriptions for ORDERS and ORDER_ITEMS tables. Evaluate the following SQL statement: SELECTo.customer_id, oi.product_id, SUM(oi.unit_price*oi.quantity) "Order Amount" FROM order_items oi JOIN orders o ON oi.order_id = o.order_id GROUP BY CUBE (o.customer_id, oi.product_id);Which three statements are true regarding the output of this SQL statement? (Choose three.)
A.It would return the subtotals for the Order Amount of every CUSTOMER_ID. B.It would return the subtotals for the Order Amount for every PRODUCT_ID.
C.It would return the subtotals for the Order Amount of every PRODUCT_ID and CUSTOMER_ID as one group.
D.It would return the subtotals for the Order Amount of every CUSTOMER_ID and PRODUCT_ID as one group.
E.It would return only the grand total for the Order Amount of every CUSTOMER_ID and PRODUCT_ID as one group.
答案:ABD
(7)View the Exhibit1 and examine the descriptions of the EMPLOYEES and DEPARTMENTS tables. The following SQL statement was executed: SELECT e.department_id, e.job_id, d.location_id, sum(e.salary) total, GROUPING(e.department_id) GRP_DEPT, GROUPING(e.job_id) GRP_JOB, GROUPING(d.location_id) GRP_LOC FROM employees e JOIN departments d ON e.department_id = d.department_id GROUP BY ROLLUP (e.department_id, e.job_id, d.location_id); View the Exhibit2 and examine the output of the command. Which two statements are true regarding the output? (Choose two.)
A.The value 1 in GRP_LOC means that the LOCATION_ID column is taken into account to generate the subtotal.
B.The value 1 in GRP_JOB and GRP_LOC means that JOB_ID and LOCATION_ID columns are not taken into account to generate the subtotal.
C.The value 1 in GRP_JOB and GRP_LOC means that the NULL value in JOB_ID and LOCATION_ID columns are taken into account to generate the subtotal.
D.The value 0 in GRP_DEPT, GRP_JOB, and GRP_LOC means that DEPARTMENT_ID, JOB_ID, and LOCATION_ID columns are taken into account to generate the subtotal.
答案:BD
(8)View the Exhibit and examine the description for EMPLOYEES and DEPARTMENTS tables. Evaluate the following SQL statement: SELECT e.department_id, e.job_id, d.location_id, sum(e.salary) total FROM employees e JOIN departments d ON e.department_id = d.department_id GROUP BY CUBE (e.department_id, e.job_id, d.location_id); Which two statements are true regarding the output of this command? (Choose two.)
A.The output would display the total salary for all the departments.
B.The output would display the total salary for all the JOB_IDs in a department.
C.The output would display only the grand total of the salary for all JOB_IDs in a LOCATION_ID.
D.The output would display the grand total of the salary for only the groups specified in the GROUP BY clause.
答案:AB
(9)Which statement is true regarding the CUBE operator in the GROUP BY clause of a SQL statement ?
A.It produces only aggregates for the groups specified in the GROUP BY clause.
B.It finds all the NULL values in the superaggregates for the groups specified in the GROUP BY clause.
C.It produces 2 n possible superaggregate combinations, if the n columns and expressions are specified in the GROUP BY clause.
D.It produces n+1 possible superaggregate combinations, if the n columns and expressions are specified in the GROUP BY clause.
答案:C
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28536251/viewspace-1876329/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- OCP課程6:SQL之使用組函式SQL函式
- OCP課程16:SQL之處理大資料SQL大資料
- OCP課程4:SQL之限制和排序資料SQL排序
- OCP課程13:SQL之使用資料字典檢視管理物件SQL物件
- OCP課程18:SQL之管理不同時區下的資料SQL
- OCP課程39:管理Ⅰ之移動資料
- OCP課程19:SQL之使用子查詢檢索資料SQL
- OCP課程56:管理II之SQL調優SQL
- OCP課程15:SQL之管理模式物件SQL模式物件
- OCP課程21:SQL之正規表示式SQL
- OCP課程12:SQL之建立其他模式物件SQL模式物件
- OCP課程9:SQL之使用集合運算子SQL
- OCP課程8:SQL之使用子查詢SQL
- OCP課程24:管理Ⅰ之資料庫安裝資料庫
- OCP課程3:SQL之使用SELECT語句檢索資料SQL
- OCP課程60:管理Ⅰ之管理資料庫空間資料庫
- OCP課程61:管理II之複製資料庫資料庫
- OCP課程25:管理Ⅰ之使用DBCA建立資料庫資料庫
- OCP課程26:管理Ⅰ之管理資料庫例項資料庫
- OCP課程50:管理II之診斷資料庫資料庫
- OCP課程5:SQL之使用單行函式SQL函式
- OCP相關資料下載
- OCP課程23:管理Ⅰ之資料庫體系結構資料庫
- OCP課程53:管理II之使用閃回資料庫資料庫
- OCP課程14:SQL之控制使用者訪問SQL
- 資料新聞的生產過程–資訊圖
- OCP課程20:SQL之分層查詢SQL
- OCP課程7:SQL之多表查詢SQL
- 資料結構課程設計報告——暢通工程資料結構
- OCP課程11:SQL之使用DDL語句建立和管理表SQL
- 【資料庫資料恢復】透過資料頁恢復Sql Server資料庫資料的過程資料庫資料恢復SQLServer
- 產生隨機密碼的sql儲存過程隨機密碼SQL儲存過程
- oracle 產生awr 報告Oracle
- 透過shell指令碼定位效能sql和生成報告指令碼SQL
- 域滲透 | kerberos認證及過程中產生的攻擊ROS
- 【案例分享】電力裝置生產資料的多層分組統計報表實現
- 資料分析中不進行資料分組會產生辛普森悖論 - TivadarDanka
- 資料庫分庫,原來 SQL 和儲存過程寫的報表咋辦?資料庫SQL儲存過程