Oracle 19c入门学习教程,从入门到精通,SQL语言基础详解:语法、使用方法与综合案例(5)

SQL语言基础详解:语法、使用方法与综合案例

SQL(Structured Query Language)是用于管理关系型数据库的标准语言。本章系统讲解 SQL 语言的基础知识,包括其分类、编写规则、数据查询、函数使用、子查询、DML 操作等,并结合 Oracle 数据库环境提供详细示例和综合性实战。


一、SQL语言简介与特点

1. SQL 简介

  • SQL 是 ANSI/ISO 标准的数据库查询与操作语言。
  • 最早由 IBM 在 1970 年代开发(SEQUEL),后被 Oracle 等厂商广泛采用。
  • 在 Oracle 中,SQL 与 PL/SQL 结合使用,支持复杂业务逻辑。

2. SQL 语言特点

特点 说明
非过程化 用户只需说明"做什么",无需指定"怎么做"
统一性 DDL、DML、DCL 均用 SQL 实现
高度可读 语法接近自然语言(如 SELECT ... FROM ... WHERE)
跨平台 支持多种数据库(Oracle、MySQL、PostgreSQL 等)

二、SQL语言的分类

类别 全称 功能 常见语句
DDL Data Definition Language 定义数据库结构 CREATE, ALTER, DROP
DML Data Manipulation Language 操作表中数据 SELECT, INSERT, UPDATE, DELETE
DCL Data Control Language 控制权限与事务 GRANT, REVOKE, COMMIT, ROLLBACK
TCL Transaction Control Language 事务控制 COMMIT, ROLLBACK, SAVEPOINT

本章重点讲解 DML(尤其是 SELECT)和部分 DDL/DCL。


三、SQL语言编写规则(Oracle)

  1. 大小写不敏感SELECTselect 等效(但字符串值区分大小写)。

  2. 语句以分号 ;/ 结束(在 SQL*Plus 中)。

  3. 关键字建议大写,提高可读性。

  4. 对象名(表、列)默认大写,若用小写需加双引号(不推荐)。

  5. 注释方式

    sql 复制代码
    -- 单行注释
    /* 多行注释 */

四、用户模式(Schema)与模式对象

1. 什么是模式(Schema)?

  • 模式是数据库对象(表、视图、索引等)的集合,属于一个数据库用户。
  • 用户名 = 模式名(如 SCOTT 用户拥有 SCOTT 模式)。

2. 模式对象示例

对象类型 说明
表(Table) 存储数据的基本单位
视图(View) 虚拟表,基于 SQL 查询
索引(Index) 加速查询
序列(Sequence) 生成唯一数字
同义词(Synonym) 对象别名

3. 示例模式:SCOTT

Oracle 自带的经典教学模式,包含以下表:

表名 说明
EMP 员工表
DEPT 部门表
SALGRADE 工资等级表
BONUS 奖金表(通常为空)
启用 SCOTT 模式(Oracle 12c+)
sql 复制代码
-- 以 sysdba 登录
CONNECT / AS SYSDBA

-- 解锁 scott 用户并设置密码
ALTER USER scott ACCOUNT UNLOCK IDENTIFIED BY tiger;

-- 连接 scott
CONNECT scott/tiger

若未安装 SCOTT 表,可手动运行 $ORACLE_HOME/rdbms/admin/scott.sql 脚本。


五、检索数据(SELECT 语句详解)

1. 简单查询(SELECT ... FROM)

sql 复制代码
-- 查询所有员工姓名和职位
SELECT ename, job 
FROM emp;

-- 使用 * 查询所有列(不推荐用于生产)
SELECT * FROM dept;

2. 筛选查询(WHERE 子句)

sql 复制代码
-- 查询工资大于 2000 的员工
SELECT ename, sal 
FROM emp 
WHERE sal > 2000;

-- 多条件筛选
SELECT ename, job, hiredate 
FROM emp 
WHERE deptno = 20 AND job = 'ANALYST';

3. 排序查询(ORDER BY)

sql 复制代码
-- 按工资降序排列
SELECT ename, sal 
FROM emp 
ORDER BY sal DESC;

-- 多列排序:先按部门升序,再按工资降序
SELECT deptno, ename, sal 
FROM emp 
ORDER BY deptno ASC, sal DESC;

4. 分组查询(GROUP BY + HAVING)

sql 复制代码
-- 统计每个部门的平均工资
SELECT deptno, AVG(sal) AS avg_salary
FROM emp
GROUP BY deptno;

-- 筛选平均工资 > 2000 的部门
SELECT deptno, AVG(sal) AS avg_salary
FROM emp
GROUP BY deptno
HAVING AVG(sal) > 2000;

⚠️ 注意:WHERE 用于筛选行,HAVING 用于筛选分组。

5. 多表关联查询(JOIN)

sql 复制代码
-- 内连接:查询员工及其部门名称
SELECT e.ename, e.job, d.dname
FROM emp e
INNER JOIN dept d ON e.deptno = d.deptno;

-- 左外连接:显示所有部门,即使没有员工
SELECT d.dname, e.ename
FROM dept d
LEFT JOIN emp e ON d.deptno = e.deptno;

-- Oracle 旧式写法(不推荐)
SELECT e.ename, d.dname
FROM emp e, dept d
WHERE e.deptno = d.deptno;

六、Oracle常用系统函数

1. 字符类函数

函数 说明 示例
UPPER(str) 转大写 UPPER('scott') → 'SCOTT'
LOWER(str) 转小写 LOWER('KING') → 'king'
SUBSTR(str, pos, len) 截取子串 SUBSTR('ORACLE', 2, 3) → 'RAC'
LENGTH(str) 字符长度 LENGTH('Hello') → 5
TRIM(str) 去除空格 TRIM(' abc ') → 'abc'
sql 复制代码
-- 示例:格式化员工姓名为大写
SELECT UPPER(ename) AS "Employee Name"
FROM emp;

2. 数字类函数

函数 说明
ROUND(n, d) 四舍五入(d 为小数位)
TRUNC(n, d) 截断(不四舍五入)
MOD(m, n) 取余
ABS(n) 绝对值
sql 复制代码
-- 计算每人奖金(假设佣金为 10%)
SELECT ename, sal, NVL(comm, 0) AS commission,
       ROUND(sal * 0.1 + NVL(comm, 0), 2) AS total_bonus
FROM emp;

3. 日期和时间类函数

函数 说明
SYSDATE 当前系统日期时间
ADD_MONTHS(date, n) 加 n 个月
MONTHS_BETWEEN(d1, d2) 两日期间月数
TO_CHAR(date, fmt) 日期转字符串
sql 复制代码
-- 查询入职超过 40 年的员工(截至 2026 年)
SELECT ename, hiredate,
       ROUND(MONTHS_BETWEEN(SYSDATE, hiredate) / 12, 1) AS years_worked
FROM emp
WHERE MONTHS_BETWEEN(SYSDATE, hiredate) / 12 > 40;

4. 转换类函数

函数 说明
TO_CHAR(value, fmt) 转字符串
TO_NUMBER(str) 转数字
TO_DATE(str, fmt) 转日期
NVL(expr1, expr2) 若 expr1 为 NULL,返回 expr2
sql 复制代码
-- 将工资格式化为货币字符串
SELECT ename, TO_CHAR(sal, '$99,999.99') AS formatted_salary
FROM emp;

5. 聚集函数(Aggregate Functions)

函数 说明
COUNT(*) 行数
SUM(col) 求和
AVG(col) 平均值
MAX(col) 最大值
MIN(col) 最小值
sql 复制代码
-- 统计员工总数、最高/最低工资、平均工资
SELECT 
  COUNT(*) AS total_employees,
  MAX(sal) AS max_salary,
  MIN(sal) AS min_salary,
  AVG(sal) AS avg_salary
FROM emp;

七、子查询(Subquery)

1. 什么是子查询?

  • 在一个 SQL 语句中嵌套另一个 SELECT 语句。
  • 子查询先执行,结果作为外层查询的条件。

2. 单行子查询(返回一行一列)

sql 复制代码
-- 查询工资高于平均工资的员工
SELECT ename, sal
FROM emp
WHERE sal > (SELECT AVG(sal) FROM emp);

3. 多行子查询(返回多行)

sql 复制代码
-- 查询在 SALES 或 RESEARCH 部门工作的员工
SELECT ename, job
FROM emp
WHERE deptno IN (
  SELECT deptno 
  FROM dept 
  WHERE dname IN ('SALES', 'RESEARCH')
);

-- 使用 ANY / ALL
SELECT ename, sal
FROM emp
WHERE sal > ANY (SELECT sal FROM emp WHERE deptno = 30); -- 高于销售部任一员工

4. 关联子查询(Correlated Subquery)

子查询引用外层查询的列。

sql 复制代码
-- 查询每个部门中工资最高的员工
SELECT e1.ename, e1.deptno, e1.sal
FROM emp e1
WHERE e1.sal = (
  SELECT MAX(e2.sal)
  FROM emp e2
  WHERE e2.deptno = e1.deptno  -- 关联条件
);

八、操作数据库(DML 语句)

1. 插入数据(INSERT)

sql 复制代码
-- 插入完整行
INSERT INTO dept (deptno, dname, loc)
VALUES (50, 'IT', 'BEIJING');

-- 插入部分列(其他列为 NULL 或默认)
INSERT INTO emp (empno, ename, job, hiredate, sal, deptno)
VALUES (8000, 'ALICE', 'DEVELOPER', SYSDATE, 5000, 50);

2. 更新数据(UPDATE)

sql 复制代码
-- 给所有 ANALYST 加薪 10%
UPDATE emp
SET sal = sal * 1.1
WHERE job = 'ANALYST';

-- 更新多个字段
UPDATE emp
SET sal = 6000, comm = 500
WHERE empno = 8000;

3. 删除数据

DELETE(可回滚,触发器生效)
sql 复制代码
-- 删除奖金为 NULL 的员工
DELETE FROM emp
WHERE comm IS NULL;
TRUNCATE(不可回滚,更快,不触发触发器)
sql 复制代码
-- 清空 bonus 表
TRUNCATE TABLE bonus;

⚠️ 区别:

  • DELETE 是 DML,可 ROLLBACK
  • TRUNCATE 是 DDL,自动 COMMIT,不能回滚。

九、综合性实战案例

案例:生成"高绩效员工年度报告"

需求

  1. 找出每个部门工资最高的员工;
  2. 显示其姓名、职位、工资、部门名、入职年限;
  3. 工资格式化为货币;
  4. 按部门编号排序;
  5. 输出到 SQL*Plus 报表。
sql 复制代码
-- 设置 SQL*Plus 环境
SET PAGESIZE 40
SET LINESIZE 150
SET FEEDBACK OFF
TTITLE CENTER 'High Performer Annual Report - &SYSDATE' SKIP 2
BTITLE CENTER 'Confidential'

-- 格式化列
COLUMN ename     HEADING "Employee Name" FORMAT A15
COLUMN job       HEADING "Job Title"      FORMAT A12
COLUMN dname     HEADING "Department"     FORMAT A15
COLUMN sal_fmt   HEADING "Salary"         FORMAT A12
COLUMN years     HEADING "Years Worked"   FORMAT 999.9

-- 主查询:使用关联子查询找部门最高薪员工
SELECT 
  e.ename,
  e.job,
  d.dname,
  TO_CHAR(e.sal, '$99,999.99') AS sal_fmt,
  ROUND(MONTHS_BETWEEN(SYSDATE, e.hiredate) / 12, 1) AS years
FROM emp e
JOIN dept d ON e.deptno = d.deptno
WHERE e.sal = (
  SELECT MAX(sal)
  FROM emp e2
  WHERE e2.deptno = e.deptno
)
ORDER BY e.deptno;

-- 清理
TTITLE OFF
BTITLE OFF
SET FEEDBACK ON

输出效果(示例):

复制代码
        High Performer Annual Report - 14-JAN-2026

Employee Name   Job Title    Department      Salary       Years Worked
--------------- ------------ --------------- ------------ ------------
KING            PRESIDENT    ACCOUNTING      $5,000.00           41.2
SCOTT           ANALYST      RESEARCH        $3,000.00           40.8
BLAKE           MANAGER      SALES           $2,850.00           41.0

十、总结

模块 核心知识点
SQL 基础 分类、规则、模式概念
数据查询 SELECT + WHERE + GROUP BY + ORDER BY + JOIN
函数 字符、数字、日期、转换、聚集
子查询 单行、多行、关联
DML INSERT / UPDATE / DELETE / TRUNCATE

💡 提示:掌握这些基础是进阶 PL/SQL、性能调优、数据库设计的前提。建议在 SQL*Plus 或 SQL Developer 中反复练习 SCOTT 模式下的各类查询。


✅ 附:快速启用 SCOTT 模式的完整脚本(若缺失)

sql 复制代码
-- 以 sys 用户运行
@?/rdbms/admin/scott.sql
ALTER USER scott IDENTIFIED BY tiger ACCOUNT UNLOCK;
相关推荐
li星野2 小时前
OpenCV4X学习-图像边缘检测、图像分割
深度学习·学习·计算机视觉
speop2 小时前
vibe-vibe |基础版
学习
好奇龙猫2 小时前
【大学院-筆記試験練習:数据库(データベース問題訓練) と 软件工程(ソフトウェア)(11)】
学习
:mnong2 小时前
通过交互式的LLM算法可视化工具学习大语言模型原理
学习·算法·语言模型
悟能不能悟2 小时前
oracle date类型默认to_char会是什么形式
数据库·oracle
JeffDingAI2 小时前
【Datawhale学习笔记】Word2Vec
笔记·学习·word2vec
Nan_Shu_6142 小时前
学习: Threejs (11)& Threejs (12)
学习
QiZhang | UESTC2 小时前
学习日记day59
学习
Engineer邓祥浩2 小时前
设计模式学习(14) 23-12 代理模式
学习·设计模式·代理模式