1. 首页 > Oracle教程 > 正文

Oracle教程FG053-SQL排序与分组

1. ORDER BY子句基础

ORDER BY子句用于对查询结果进行排序,可以按照一个或多个列进行升序或降序排序。它是SQL查询中常用的子句之一,用于控制结果集的顺序。更多学习教程www.fgedu.net.cn

ORDER BY语法:SELECT column1, column2, … FROM table_name ORDER BY column1 [ASC|DESC], column2 [ASC|DESC], …;

— 按工资升序排序
SELECT employee_id, first_name, last_name, salary
FROM employees
ORDER BY salary;EMPLOYEE_ID EMP_NAME EMP_EMP_EMP_LAST_NAME SALARY
———– ——————– ————————- ———-
104 Bruce Ernst 6000
103 Alexander Hunold 9000
101 Neena Kochhar 17000
102 Lex De Haan 17000
100 Steven King 24000

— 按工资降序排序
SELECT employee_id, first_name, last_name, salary
FROM employees
ORDER BY salary DESC;EMPLOYEE_ID EMP_NAME EMP_EMP_EMP_LAST_NAME SALARY
———– ——————– ————————- ———-
100 Steven King 24000
101 Neena Kochhar 17000
102 Lex De Haan 17000
103 Alexander Hunold 9000
104 Bruce Ernst 6000

2. 多列排序

可以按照多个列进行排序,先按照第一列排序,然后按照第二列排序,以此类推。

— 按部门ID升序,工资降序排序
SELECT employee_id, department_id, first_name, last_name, salary
FROM employees
ORDER BY department_id, salary DESC;EMPLOYEE_ID DEPARTMENT_ID EMP_NAME EMP_EMP_EMP_LAST_NAME SALARY
———– ————- ——————– ————————- ———-
103 60 Alexander Hunold 9000
104 60 Bruce Ernst 6000
100 90 Steven King 24000
101 90 Neena Kochhar 17000
102 90 Lex De Haan 17000

— 按工作ID和雇佣日期排序
SELECT employee_id, job_id, hire_date, first_name, last_name
FROM employees
ORDER BY job_id, hire_date;EMPLOYEE_ID JOB_ID HIRE_DATE EMP_NAME EMP_EMP_EMP_LAST_NAME
———– ———- ———- ——————– ————————-
100 AD_PRES 17-JUN-03 Steven King
102 AD_VP 13-JAN-01 Lex De Haan
101 AD_VP 21-SEP-05 Neena Kochhar
103 IT_PROG 03-JAN-06 Alexander Hunold
104 IT_PROG 21-MAY-07 Bruce Ernst

3. NULL值排序

在排序时,NULL值默认被视为最小值,出现在升序排序的开头或降序排序的末尾。

— 按commission_pct升序排序(NULL值在前)
SELECT employee_id, first_name, last_name, commission_pct
FROM employees
ORDER BY commission_pct;EMPLOYEE_ID EMP_NAME EMP_EMP_EMP_LAST_NAME COMMISSION_PCT
———– ——————– ————————- ————–
100 Steven King
101 Neena Kochhar
102 Lex De Haan
103 Alexander Hunold
104 Bruce Ernst

— 按commission_pct降序排序(NULL值在后)
SELECT employee_id, first_name, last_name, commission_pct
FROM employees
ORDER BY commission_pct DESC;EMPLOYEE_ID EMP_NAME EMP_EMP_EMP_LAST_NAME COMMISSION_PCT
———– ——————– ————————- ————–
100 Steven King
101 Neena Kochhar
102 Lex De Haan
103 Alexander Hunold
104 Bruce Ernst

— 使用NULLS FIRST和NULLS LAST控制NULL值位置
SELECT employee_id, first_name, last_name, commission_pct
FROM employees
ORDER BY commission_pct NULLS LAST;EMPLOYEE_ID EMP_NAME EMP_EMP_EMP_LAST_NAME COMMISSION_PCT
———– ——————– ————————- ————–
100 Steven King
101 Neena Kochhar
102 Lex De Haan
103 Alexander Hunold
104 Bruce Ernst

4. 表达式排序

可以使用表达式进行排序,例如使用函数或计算表达式。

— 按年薪排序
SELECT employee_id, first_name, last_name, salary, salary * 12 AS annual_salary
FROM employees
ORDER BY annual_salary DESC;EMPLOYEE_ID EMP_NAME EMP_EMP_EMP_LAST_NAME SALARY ANNUAL_SALARY
———– ——————– ————————- ———- ————-
100 Steven King 24000 288000
101 Neena Kochhar 17000 204000
102 Lex De Haan 17000 204000
103 Alexander Hunold 9000 108000
104 Bruce Ernst 6000 72000

— 按名字长度排序
SELECT employee_id, first_name, last_name, LENGTH(first_name) AS name_length
FROM employees
ORDER BY name_length DESC;EMPLOYEE_ID EMP_NAME EMP_EMP_EMP_LAST_NAME NAME_LENGTH
———– ——————– ————————- ———–
103 Alexander Hunold 9
100 Steven King 6
104 Bruce Ernst 5
101 Neena Kochhar 5
102 Lex De Haan 3

5. GROUP BY子句基础

GROUP BY子句用于对查询结果进行分组,通常与聚合函数一起使用,计算每个组的汇总值。

GROUP BY语法:SELECT column1, aggregate_function(column2) FROM table_name GROUP BY column1;

— 按部门ID分组,计算每个部门的平均工资
SELECT department_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id;DEPARTMENT_ID AVG_SALARY
————- ———–
60 7500
90 19333.3333333333333333333333333333333

— 按工作ID分组,计算每个工作的员工数量
SELECT job_id, COUNT(*) AS employee_count
FROM employees
GROUP BY job_id;JOB_ID EMPLOYEE_COUNT
———- —————
AD_PRES 1
AD_VP 2
IT_PROG 2

6. 多列分组

可以按照多个列进行分组,先按照第一列分组,然后按照第二列分组,以此类推。

— 按部门ID和工作ID分组,计算每个部门每个工作的平均工资
SELECT department_id, job_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id, job_id;DEPARTMENT_ID JOB_ID AVG_SALARY
————- ———- —————
60 IT_PROG 7500
90 AD_PRES 24000
90 AD_VP 17000

— 按部门ID和工作ID分组,计算每个部门每个工作的员工数量和总工资
SELECT department_id, job_id, COUNT(*) AS employee_count, SUM(salary) AS total_salary
FROM employees
GROUP BY department_id, job_id;DEPARTMENT_ID JOB_ID EMPLOYEE_COUNT TOTAL_SALARY
————- ———- ————— ————
60 IT_PROG 2 15000
90 AD_PRES 1 24000
90 AD_VP 2 34000

7. HAVING子句

HAVING子句用于过滤分组后的结果,类似于WHERE子句,但它作用于分组后的结果。

— 按部门ID分组,计算每个部门的平均工资,只显示平均工资大于10000的部门
SELECT department_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id
HAVING AVG(salary) > 10000;DEPARTMENT_ID AVG_SALARY
————- ———–
90 19333.3333333333333333333333333333333

— 按工作ID分组,计算每个工作的员工数量,只显示员工数量大于1的工作
SELECT job_id, COUNT(*) AS employee_count
FROM employees
GROUP BY job_id
HAVING COUNT(*) > 1;JOB_ID EMPLOYEE_COUNT
———- —————
AD_VP 2
IT_PROG 2

— 复杂的HAVING子句
SELECT department_id, job_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id, job_id
HAVING AVG(salary) > 8000 AND department_id = 90;DEPARTMENT_ID JOB_ID AVG_SALARY
————- ———- —————
90 AD_PRES 24000
90 AD_VP 17000

8. 最佳实践

风哥提示:SQL排序与分组的最佳实践:
1. 合理使用ORDER BY子句对结果进行排序,提高可读性
2. 对于大型结果集,考虑使用分页查询,避免排序大量数据
3. 为ORDER BY子句中的列创建索引,提高排序性能
4. 合理使用GROUP BY子句进行数据汇总
5. 结合聚合函数使用GROUP BY,计算有意义的统计信息
6. 使用HAVING子句过滤分组后的结果,而不是WHERE子句
7. 对于复杂的分组查询,考虑使用子查询或临时表
8. 注意NULL值在排序和分组中的处理
9. 避免在GROUP BY子句中使用复杂的表达式
10. 定期分析查询性能,优化排序和分组操作

生产环境建议:在生产环境中,应尽量减少排序操作的复杂度,特别是对于大型表。对于需要频繁排序的列,建议创建索引。同时,合理使用分组操作,避免对大量数据进行分组计算,影响查询性能。

更多视频教程www.fgedu.net.cn

学习交流加群风哥微信: itpux-com

学习交流加群风哥QQ113257174

更多学习教程公众号风哥教程itpux_com

from oracle:www.itpux.com

本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息