Teradata 学习笔记2

分组与聚合:

聚合函数
聚合操作用来完成对一组指定数据进行聚合计算,完成聚合计算的函数主要
有:
! MIN 求最小值,计算中忽略空值。
! MAX 求最大值,计算中忽略空值。
! SUM 求合计,计算中忽略空值。
! COUNT 返回个数,计算中包括空值。
! AVG 求平均值,计算中忽略空值。

利用GROUP BY和聚合函数可以实现分组累计。举例来说,如果要求显示各
个部门的薪水合计,可以使用下面的语句。
SELECT department_number
,SUM (salary_amount)
FROM employee
GROUP BY department_number;

需要注意的是,在SELECT子句中不作分组累计的所有字段必须出现在
GROUP BY子句中

以上例来说,Department_Number字段未作累计,因此它必须出现在GROUP
BY子句中。这条基本规则必须牢记。

WHERE子句和GROUP BY子句
WHERE子句和GROUP BY子句同时使用时,GROUP BY只对符合WHERE限
制的数据记录进行分组聚合计算。换言之,在作真正的聚合计算之前,WHERE子
句将不符合条件的数据记录剔除了。
 
例:部门401和403的合计薪水是多少?
SELECT department_number
,SUM (salary_amount)
FROM employee
WHERE department_number IN (401, 403)
GROUP BY department_number
;

GROUP BY和ORDER BY
在GROUP BY后加上ORDER BY,可以使得分组统计按照指定的秩序来显
示。例如,按部门编号顺序显示部门人数、合计薪水、部门最高薪水、部门最底薪
水和部门平均薪水,可以使用下面的SQL语句:
SELECT department_number (TITLE 'DEPT')
,COUNT (*) (TITLE '#_EMPS')
,SUM (salary_amount) (TITLE 'TOTAL')
(FORMAT 'zz,zzz,zz9.99')
,MAX (salary_amount) (TITLE 'HIGHEST')
(FORMAT 'zz,zzz,zz9.99')
,MIN (salary_amount) (TITLE 'LOWEST')
(FORMAT 'zz,zzz,zz9.99')
,AVG (salary_amount) (TITLE 'AVERAGE')
(FORMAT 'zz,zzz,zz9.99')
FROM employee
GROUP BY department_number
ORDER BY department_number
;

当GROUP BY中有多个字段时,它只能产生一个级别
的汇总,而且是按照最后一个字段(这里是job_code)来进行汇总。

GROUP BY和HAVING条件限定
HAVING条件子句是和GROUP一起使用的,用来对分组统计的结果进行限
定,只返回满足其条件的分组统计结果。
举例来说,按部门编号顺序显示部门人数、合计薪水、部门最高薪水、部门
最低薪水和部门平均薪水,条件是只显示部门平均薪水小于36000的部门。
SELECT department_number (TITLE 'DEPT')
,COUNT (*) (TITLE '#_EMPS')
,SUM (salary_amount) (TITLE 'TOTAL')
(FORMAT 'zz,zzz,zz9.99')
,MAX (salary_amount) (TITLE 'HIGHEST')
(FORMAT 'zz,zzz,zz9.99')
,MIN (salary_amount) (TITLE 'LOWEST')
(FORMAT 'zz,zzz,zz9.99)

,AVG (salary_amount) (TITLE 'AVERAGE')

(FORMAT 'zz,zzz,zz9.99')
FROM employee
GROUP BY department_number
HAVING AVG (salary_amount) < 36000;

GROUP BY小结
在进行分组聚合操作时,要特别注意以下各点:
! WHERE:用来限定参与分组聚合运算的表的数据记录,只有满足条件的
数据记录才会被选中参与分组聚合。
! GROUP BY:将符合WHERE条件子句的记录进行分组
! HAVING:用来限定可以返回的分组聚合的结果
! ORDER BY:用来指定结果的输出顺序
 总计与小计:

本章主要学习Select语句中的总计(totals)和小计(subtotals)功能。通过本章的学
习,我们将能够:
! 利用 WITH BY语句创建子计(subtotals)
! 利用 WITH语句建立最后的总计(totals)
! 利用 DISTINCT选项剔除重复结果

利用WITH BY进行数据小计
WITH BY的主要特点包括:
! 它为明细数据表创建分类小计。
! 跟GROUP BY不同的是,WITH BY没有剔除明细记录,而是在明细记录
后面按照分类增加小计行。
! 可以允许多于一个字段进行小计,即小计当中可以嵌套小计。
! 输出结果将根据BY后面的所有字段自动进行排序。
! 它是Teradata的一个扩展特性。

请看下面的一些例子。为了说明方便,在下面的诸例子中均利用了雇员表。
 
1.利用WITH BY产生基本报表。

例如在Employee表中,欲显示所有雇员姓和工资并要求按部门进行小计。其
语句如下:
SELECT last_name AS NAME
,salary_amount AS SALARY
,department_number AS DEPT
FROM employee
WITH SUM (salary) BY DEPT;

返回的报表如下所示:
NAME SALARY DEPT
Stein 29450.00 301
Kanieski 29250.00 301
--------------
Sum(SALARY)58700.00
Johnson 36300.00 401
Trader 37850.00 401
--------------
Sum(SALARY)74150.00
Villegas 49700.00 403
Ryan 31200.00 403
--------------
Sum(SALARY) 80900.00

2. WITH BY多聚合计算

如欲显示雇员名和工资,并要求按照部门进行小计和计算平均值。其语法如
下:
SELECT last_name AS NAME
,salary_amount AS SALARY
,department_number AS DEPT
FROM employee
WITH SUM (salary) (TITLE `Dept Total')
,AVG (salary) (TITLE `Dept Avg ') BY DEPT;

返回的报表格式如下:
NAME SALARY DEPT
Stein 29450.00 301
Kanieski 29250.00 301
--------------
Dept Total 58700.00
Dept Avg 29350.00
Johnson 36300.00 401
Trader 37850.00 401
--------------
Dept Total 74150.00
Dept Avg 37075.00
Villegas 49700.00 403
Ryan 31200.00 403
--------------
Dept Total 80900.00
Dept Avg 40450.00

这里同时显示了部门小计和平均薪水

3. WITH BY多层小计
利用WITH BY进行多层小计时,越在后面的字段表明它的小计和排序层次越
高。看下面的例子:
列出部门401和501所有雇员的编号和工资,要求按照部门进行工资小计,在
同一部门中还要求按照工作代码进行小计。其语句如下:
SELECT department_number AS Dept
,job_code AS Job
,employee_number AS Emp
,salary_amount AS Sal
FROM employee
WHERE department_number IN (401, 501)
WITH SUM(salary_amount) (TITLE 'Job Total') BY Job
WITH SUM(salary_amount) (TITLE 'DEPT TOTAL') BY Dept;

返回结果如下:
Dept Job Emp Sal
401 411100 1003 37850.00
------------
Job Total 37850.00
401 412101 1004 36300.00

401 412101 1001 25525.00
401 412101 1010 46000.00
------------
Job Total 107825.00
401 412102 1013 24500.00
401 412102 1022 32300.00
------------
Job Total 56800.00
401 413201 1002 43100.00
------------
Job Total 43100.00
------------
DEPT TOTAL 245575.00

利用WITH语句产生最后的总计
如果在WITH语句中不带BY则只产生总计。如下面的例子:
列出部门301所有的雇员编号和其工资数,并对该部门的工资作统计,语句如
下:
SELECT employee_number
,salary_amount
FROM employee
WHERE department_number = 301
WITH SUM(salary_amount) (TITLE 'GRAND TOTAL')
ORDER BY employee_number;

返回结果如下:
employee_number salary_amount
1006 29450.00
1008 29250.00
1019 57700.00
-------------
GRAND TOTAL 116400.00

DISTINCT修饰语
DISTINCT主要用来剔除重复的数据记录。利用DISTINCT修饰语可以用来作
一些特定的计算。
下列语句没有使用DISTINCT修饰语:
SELECT employee_number
,department_number
,manager_employee_number (NAMED manager)
FROM employee
WHERE employee_number BETWEEN 1003 AND 1008
WITH COUNT (manager) (TITLE 'TOTAL MANAGERS');

其结果为:
employee_number department_number manager
1006 301 1019
1005 403 801

1003 401 801
1007 403 1005
1008 301 1019
1004 401 1003
TOTAL MANAGERS 6
 
如果使用DISTINCT修饰语,如下:

SELECT employee_number
,department_number
,manager_employee_number AS manager
FROM employee
WHERE employee_number BETWEEN 1003 AND 1008
WITH COUNT (DISTINCT manager) (TITLE 'TOTAL MANAGERS');
 
则结果为:
employee_number department_number manager
1006 301 1019
1006 301 1019
1005 403 801
1003 401 801
1007 403 1005
1008 301 1019
1004 401 1003
TOTAL MANAGERS 4

 从这里可以看到,加上DISTINCT后,重复的数据记录被剔除了。
1. WITH BY, WITH和ORDER BY的联合使用
假设要显示所有雇员的姓及其工资,按部门进行小计,得出最后总计,并要
求按姓排序,则语句为:
SELECT last_name AS NAME
,salary_amount AS SALARY
,department_number AS DEPT
FROM employee
WITH SUM (SALARY) BY DEPT
WITH SUM (SALARY) (TITLE 'GRAND TOTAL')
ORDER BY NAME;

结果如下:
NAME SALARY DEPT
Kanieski 29250.00 301
Stein 29450.00 301
-------------
Sum (SALARY) 58700.00
Johnson 36300.00 401
Trader 37850.00 401
-------------
Sum (SALARY) 74150.00

Ryan 31200.00 403
Villegas 49700.00 403
-------------
Sum (SALARY) 80900.00
-------------
GRAND TOTAL 213750.00

2. WITH和GROUP BY的联合使用
利用WITH和GROUP BY可以建立最后的总计。看下面的例子:
列出每个部门的工资总计和平均值,最后列出整个公司的工资总额和平均
值,则语句如下:
SELECT department_number (TITLE 'dept_no')
,SUM (salary_amount)
,AVG (salary_amount)
FROM employee
GROUP BY department_number
WITH SUM (salary_amount) (TITLE 'GRAND TOTAL')
,AVG (salary_amount) (TITLE '')
ORDER BY department_number;

结果如下:
dept_no SUM (salary_amount) AVG (salary_amount)
301 58700.00 29350.00
401 74150.00 37075.00
403 80900.00 40450.00

GRAND TOTAL 213750.00 35635.00

WITH BY和WITH总结:

WITH BY的基本格式为:
格式:WITH 汇总列表 BY 分类列表ASC/DESC

特点如下:
! 为详细数据列表建立总计和小计行
! 汇总列表可以多于一个字段
! 分类列表可以多于一个字段
! 分类列表的列已经隐含了ORDER BY功能
! WITH. . . BY后的相应字段决定了主要的排序键
! 一个 SQL语句可以有多个WITH BY子句
! 第一个 WITH BY排序层次最低
! ORDER BY用来指定其它附加的子排序,指在某个字段内的进一步排序,
如部门内再按薪资高低来进一步排序。
 
WITH的基本格式为:
格式:WITH 汇总列表

WITH的特点如下:
! 提供最终或总体的总计
! 汇总列表可以多于一个字段

集合操作:

集合操作主要包括:合并操作(UNION)、相交操作(INTERSECT)和排外操作
(EXCEPT)。

相交操作
返回在每一个SELECT语句结果中都存在的记录。可由下图16-1形象表示:

Teradata 学习笔记2_第1张图片

INTERSECT用来连接两个SELECT查询,这两个查询所返回的数据集必须具
有相同的字段数和数据类型。经相交操作后,只有在两个查询中完全相同的数据行
才会返回。举例来说,如果第一个查询返回的记录为A、B、C,第二个查询返回
的记录为B、C、D,则相交后的结果为B和C。

合并操作
合并所有SELECT语句的结果,重复记录在结果集中只显示一次。如下图16-2
所示。

Teradata 学习笔记2_第2张图片

UNION连接两个或更多的查询,虽然每个查询的字段名可以不相同,但必须
具有相同的字段数和数据类型。

排它操作:
返回第一个SELECT语句结果中除第二个SELECT语句结果中以外的所有记
录。如图16-3所示。

Teradata 学习笔记2_第3张图片

同样,两个SELECT查询所返回的字段名可以不同,但数目和数据类型必须一
致。在有些数据库系统中,排它操作也称为相减操作(MINUS)。

合并操作:

这里总结一下使用UNION的基本规则:
1. 所有的SELECT语句:
! 必须要有同样多的表达式数目
! 相关表达式的域必须兼容
2. 第一个SELECT语句:
! 决定输出的格式(FORMAT)
! 决定输出的标题(TITLE)
3. 最后一个SELECT语句:
! 包含整个结果集的ORDER BY选项(如果有的话)
! ORDER BY后面的列最好用数字顺序表示

例:谁是经理1019并且谁为他工作?
SELECT first_name
,last_name
,'employee' (TITLE 'employee//type')
FROM employee

WHERE manager_employee_number = 1019
UNION
SELECT first_name
,last_name
,' manager '
FROM employee
WHERE employee_number = 1019
ORDER BY 2;

返回结果如下:
employee
first_name last_name type
Carol Kanieski employee
Ron Kubic manager
John Stein employee

相交操作
我们通过例子来说明。列出所有拥有下属雇员的部门经理(有些部门经理可能
没有下属)。
SELECT manager_employee_number
FROM employee
INTERSECT
SELECT manager_employee_number
FROM department
ORDER BY 1;

结果为:
manager_employee_number
801
1003
1005
1011
1017
1019
1025

排它操作
例子:列出所有没有下属雇员的部门经理。
SELECT manager_employee_number
FROM department
EXCEPT
SELECT manager_employee_number
FROM employee
ORDER BY 1;
 
结果为:
manager_employee_number
1016
1099

关于集合操作的补充规则
我们将有关集合操作的一些补充规则列举如下:
! 在子查询中不能使用集合操作
! 在定义视图时不能使用集合操作
! 不能包含WITH或WITH BY子句
! 集合操作的优先级为:INTERSECT第一,其后分别为UNION和
EXCEPT,从左到右。可以使用括号改变优先级。
! 每一个SELECT语句必须有一个FROM <表名>的子句
! 每个单独的SELECT语句中可以使用GROUP BY
! Group By不能用于或影响整个返回结果集
! 重复记录将会抛弃,除非使用ALL选项
 

 

你可能感兴趣的:(Teradata)