SELECT语句基础
SELECT语句是SQL中最常用的查询语句,用于从数据库中检索数据。
基本语法
sql
SELECT [DISTINCT] column_list
FROM table_name
[WHERE condition]
[ORDER BY column_list [ASC|DESC]]
[LIMIT number];
查询所有列
sql
-- 查询employees表中的所有数据
SELECT * FROM employees;
-- 查询departments表中的所有数据
SELECT * FROM departments;
查询指定列
sql
-- 查询员工的姓名和薪资
SELECT first_name, last_name, salary FROM employees;
-- 查询部门名称
SELECT department_name FROM departments;
使用列别名
sql
-- 使用AS关键字设置别名
SELECT first_name AS "名字", last_name AS "姓氏", salary AS "薪资" FROM employees;
-- 省略AS关键字
SELECT first_name "名字", last_name "姓氏", salary "薪资" FROM employees;
-- 使用表达式别名
SELECT first_name || ' ' || last_name AS "全名", salary*12 AS "年薪" FROM employees;
4.2 WHERE子句条件查询
WHERE子句用于筛选满足特定条件的记录。
比较运算符
sql
-- 等于
SELECT * FROM employees WHERE salary = 17000;
-- 不等于
SELECT * FROM employees WHERE department_id != 90;
SELECT * FROM employees WHERE department_id <> 90;
-- 大于、小于
SELECT * FROM employees WHERE salary > 10000;
SELECT * FROM employees WHERE hire_date < TO_DATE('2000-01-01', 'YYYY-MM-DD');
-- 大于等于、小于等于
SELECT * FROM employees WHERE salary >= 15000;
SELECT * FROM employees WHERE salary <= 10000;
逻辑运算符
sql
-- AND运算符
SELECT * FROM employees WHERE department_id = 60 AND salary > 8000;
-- OR运算符
SELECT * FROM employees WHERE department_id = 60 OR department_id = 90;
-- NOT运算符
SELECT * FROM employees WHERE NOT department_id = 90;
范围查询
sql
-- BETWEEN...AND...
SELECT * FROM employees WHERE salary BETWEEN 10000 AND 20000;
-- IN运算符
SELECT * FROM employees WHERE department_id IN (60, 90, 100);
-- NOT IN运算符
SELECT * FROM employees WHERE department_id NOT IN (60, 90, 100);
模糊查询
sql
-- LIKE运算符(%匹配任意字符,_匹配单个字符)
SELECT * FROM employees WHERE first_name LIKE 'A%'; -- 姓氏以A开头
SELECT * FROM employees WHERE first_name LIKE '_a%'; -- 第二个字母是a
SELECT * FROM employees WHERE first_name LIKE '____'; -- 姓氏恰好4个字符
-- NOT LIKE运算符
SELECT * FROM employees WHERE first_name NOT LIKE 'A%';
空值查询
sql
-- IS NULL查询空值
SELECT * FROM employees WHERE commission_pct IS NULL;
-- IS NOT NULL查询非空值
SELECT * FROM employees WHERE commission_pct IS NOT NULL;
4.3 排序查询
ORDER BY子句用于对查询结果进行排序。
单列排序
sql
-- 按薪资升序排列(默认)
SELECT first_name, last_name, salary FROM employees ORDER BY salary;
-- 按薪资降序排列
SELECT first_name, last_name, salary FROM employees ORDER BY salary DESC;
-- 按入职日期升序排列
SELECT first_name, last_name, hire_date FROM employees ORDER BY hire_date;
多列排序
sql
-- 先按部门编号升序,再按薪资降序
SELECT department_id, first_name, last_name, salary
FROM employees
ORDER BY department_id ASC, salary DESC;
-- 按多个字段排序
SELECT department_id, job_id, first_name, last_name, salary
FROM employees
ORDER BY department_id, job_id DESC, salary;
按列别名排序
sql
-- 按计算列排序
SELECT first_name, last_name, salary*12 AS annual_salary
FROM employees
ORDER BY annual_salary DESC;
4.4 函数使用
Oracle提供了丰富的内置函数用于数据处理。
字符函数
sql
-- UPPER函数:转换为大写
SELECT UPPER(first_name) FROM employees;
-- LOWER函数:转换为小写
SELECT LOWER(last_name) FROM employees;
-- INITCAP函数:首字母大写
SELECT INITCAP(email) FROM employees;
-- CONCAT函数:连接字符串
SELECT CONCAT(first_name, ' ') || last_name AS full_name FROM employees;
-- SUBSTR函数:截取子串
SELECT SUBSTR(first_name, 1, 3) FROM employees;
-- LENGTH函数:获取字符串长度
SELECT first_name, LENGTH(first_name) FROM employees;
-- REPLACE函数:替换字符串
SELECT REPLACE(phone_number, '.', '-') FROM employees;
数值函数
sql
-- ROUND函数:四舍五入
SELECT salary, ROUND(salary/7, 2) AS weekly_salary FROM employees;
-- TRUNC函数:截断
SELECT salary, TRUNC(salary/7) AS weekly_salary FROM employees;
-- MOD函数:求余数
SELECT employee_id, MOD(employee_id, 2) AS remainder FROM employees;
-- ABS函数:绝对值
SELECT ABS(-100) FROM dual;
-- CEIL函数:向上取整
SELECT CEIL(45.2) FROM dual;
-- FLOOR函数:向下取整
SELECT FLOOR(45.8) FROM dual;
日期函数
sql
-- SYSDATE函数:获取当前日期时间
SELECT SYSDATE FROM dual;
-- ADD_MONTHS函数:增加月份
SELECT hire_date, ADD_MONTHS(hire_date, 6) AS review_date FROM employees;
-- MONTHS_BETWEEN函数:计算月份差
SELECT first_name, hire_date,
ROUND(MONTHS_BETWEEN(SYSDATE, hire_date)) AS months_worked
FROM employees;
-- NEXT_DAY函数:下一个指定星期几
SELECT NEXT_DAY(SYSDATE, 'MONDAY') FROM dual;
-- LAST_DAY函数:月末日期
SELECT LAST_DAY(SYSDATE) FROM dual;
-- EXTRACT函数:提取日期部分
SELECT EXTRACT(YEAR FROM hire_date) AS hire_year FROM employees;
转换函数
sql
-- TO_CHAR函数:转换为字符
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') FROM dual;
SELECT first_name, TO_CHAR(salary, '$999,999.99') AS formatted_salary FROM employees;
-- TO_NUMBER函数:转换为数值
SELECT TO_NUMBER('12345') FROM dual;
-- TO_DATE函数:转换为日期
SELECT TO_DATE('2023-12-25', 'YYYY-MM-DD') FROM dual;
4.5 分组查询
GROUP BY子句用于将查询结果按指定列分组。
基本分组
sql
-- 按部门分组统计员工数量
SELECT department_id, COUNT(*) AS employee_count
FROM employees
GROUP BY department_id;
-- 按部门分组统计平均薪资
SELECT department_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id;
多列分组
sql
-- 按部门和职位分组
SELECT department_id, job_id, COUNT(*) AS employee_count, AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id, job_id
ORDER BY department_id, job_id;
HAVING子句
HAVING子句用于对分组后的结果进行筛选。
sql
-- 查询员工数量大于5的部门
SELECT department_id, COUNT(*) AS employee_count
FROM employees
GROUP BY department_id
HAVING COUNT(*) > 5;
-- 查询平均薪资大于10000的部门
SELECT department_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id
HAVING AVG(salary) > 10000;
聚合函数
sql
-- COUNT函数:统计记录数
SELECT COUNT(*) FROM employees;
SELECT COUNT(commission_pct) FROM employees; -- 不统计NULL值
-- SUM函数:求和
SELECT SUM(salary) AS total_salary FROM employees;
-- AVG函数:平均值
SELECT AVG(salary) AS avg_salary FROM employees;
-- MAX函数:最大值
SELECT MAX(salary) AS max_salary FROM employees;
-- MIN函数:最小值
SELECT MIN(salary) AS min_salary FROM employees;
4.6 多表连接查询
连接查询用于从多个相关表中检索数据。
内连接(INNER JOIN)
sql
-- 显示员工姓名和所属部门名称
SELECT e.first_name, e.last_name, d.department_name
FROM employees e
INNER JOIN departments d ON e.department_id = d.department_id;
-- 使用传统语法
SELECT e.first_name, e.last_name, d.department_name
FROM employees e, departments d
WHERE e.department_id = d.department_id;
外连接
sql
-- 左外连接(LEFT JOIN)
SELECT e.first_name, e.last_name, d.department_name
FROM employees e
LEFT JOIN departments d ON e.department_id = d.department_id;
-- 右外连接(RIGHT JOIN)
SELECT e.first_name, e.last_name, d.department_name
FROM employees e
RIGHT JOIN departments d ON e.department_id = d.department_id;
-- 全外连接(FULL JOIN)
SELECT e.first_name, e.last_name, d.department_name
FROM employees e
FULL JOIN departments d ON e.department_id = d.department_id;
自连接
sql
-- 查询员工及其管理者信息
SELECT e.first_name || ' ' || e.last_name AS employee,
m.first_name || ' ' || m.last_name AS manager
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.employee_id;
多表连接
sql
-- 连接三个表:员工、部门、工作地点
SELECT e.first_name, e.last_name, d.department_name, l.city
FROM employees e
JOIN departments d ON e.department_id = d.department_id
JOIN locations l ON d.location_id = l.location_id;
4.7 子查询
子查询是嵌套在其他查询中的查询语句。
单行子查询
sql
-- 查询薪资高于平均薪资的员工
SELECT first_name, last_name, salary
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);
-- 查询与员工100同部门的员工
SELECT first_name, last_name, department_id
FROM employees
WHERE department_id = (SELECT department_id FROM employees WHERE employee_id = 100);
多行子查询
sql
-- 使用IN运算符
SELECT first_name, last_name, department_id
FROM employees
WHERE department_id IN (SELECT department_id FROM departments WHERE location_id = 1700);
-- 使用ANY运算符
SELECT first_name, last_name, salary
FROM employees
WHERE salary > ANY (SELECT salary FROM employees WHERE department_id = 60);
-- 使用ALL运算符
SELECT first_name, last_name, salary
FROM employees
WHERE salary > ALL (SELECT salary FROM employees WHERE department_id = 60);
相关子查询
sql
-- 查询每个部门薪资最高的员工
SELECT department_id, first_name, last_name, salary
FROM employees e1
WHERE salary = (SELECT MAX(salary)
FROM employees e2
WHERE e2.department_id = e1.department_id);
4.8 集合操作
集合操作用于合并多个查询结果。
UNION操作
sql
-- 合并两个查询结果(去除重复)
SELECT first_name, last_name FROM employees WHERE department_id = 60
UNION
SELECT first_name, last_name FROM employees WHERE department_id = 90;
UNION ALL操作
sql
-- 合并两个查询结果(保留重复)
SELECT first_name, last_name FROM employees WHERE department_id = 60
UNION ALL
SELECT first_name, last_name FROM employees WHERE department_id = 90;
INTERSECT操作
sql
-- 返回两个查询结果的交集
SELECT department_id FROM departments WHERE location_id = 1700
INTERSECT
SELECT department_id FROM employees WHERE salary > 10000;
MINUS操作
sql
-- 返回第一个查询结果中存在但第二个查询结果中不存在的记录
SELECT department_id FROM departments
MINUS
SELECT department_id FROM employees;
4.9 本章小结
本章详细介绍了Oracle数据库中的基本查询操作,包括SELECT语句的使用、WHERE条件筛选、排序、函数使用、分组查询、多表连接、子查询和集合操作等。掌握这些查询技能是进行数据分析和报表生成的基础。
练习题
- 查询所有员工的姓名、邮箱和薪资,并按薪资降序排列
- 查询薪资在10000到20000之间的员工信息
- 查询姓氏以'S'开头的员工
- 查询没有佣金的员工数量
- 按部门统计员工数量和平均薪资
- 查询每个部门薪资最高的员工信息
- 查询员工姓名及其管理者姓名
- 使用集合操作查询在部门60或部门90工作但不在部门100工作的员工