说明:Oracle 和 MySQL SQL 语法存在不少差异,本篇聚焦 Oracle 特有的写法、规则与工具,适合运维、数据库入门学习。
1.1 DQL
DQL (Data Query Language):数据查询语言,使用 SQL 语句实现对数据表的查询。 SQL:Structured Query Language,结构化查询语言。 Oracle 的 DQL 核心就是 SELECT 语句,语法结构完整,支持简单单表查询、多表关联、分组统计、排序、分析查询等各类业务场景。
1.1.1 基本语法结构
Oracle DQL 标准语法:
SELECT [DISTINCT] 列名1, 列名2, ... | *
FROM 表名
[WHERE 条件]
[GROUP BY 列名]
[HAVING 分组后筛选条件]
[ORDER BY 列名 [ASC|DESC] [NULLS FIRST | NULLS LAST]];
SELECT子句:指定需要查询的列、表达式;*代表查询全部列FROM子句:指定数据来源表WHERE:行过滤,分组之前筛选原始数据GROUP BY:按照指定字段分组,配合聚合函数统计HAVING:对分组统计之后的结果再次过滤(可以使用聚合函数)ORDER BY:结果集排序,Oracle 独有NULLS FIRST / NULLS LAST控制空值排在最前或最后
关键字说明:
-
DISTINCT:去除结果集中重复行 -
虚拟表
DUAL:Oracle 特有,用于简单计算、函数测试,没有实际业务数据-- Oracle 特有,测试计算
SELECT 1+3 FROM DUAL;
WHERE 支持条件:
- 比较运算符:
=, >, <, >=, <=, !=, <> - 范围:
BETWEEN ... AND ... - 集合:
IN(值1,值2,...) - 模糊匹配:
LIKE,%匹配任意多个字符,_匹配单个字符 - 空值判断:
IS NULL/IS NOT NULL,不能使用 = NULL - 逻辑运算符:
AND, OR, NOT,优先级:NOT > AND > OR
ORDER BY 排序:
ASC:升序,默认DESC:降序- 多列排序:先按第一列排序,第一列相同再按第二列
NULLS FIRST:空值放最前面;NULLS LAST:空值放最后(MySQL 没有这个写法)
1.1.2 SELECT 的基础使用
1.1.2.1 SELECT 语句的功能
基础格式:
SELECT *|{[DISTINCT] column [alias],...}
FROM table;
SELECT:指定展示哪些列,*代表所有列FROM:指定数据来自哪张表
示例:
-- 查询employees表所有列
SELECT * FROM employees;
-- 查询指定字段:员工编号、名字
SELECT employee_id,first_name FROM employees;
1.1.2.2 编写 SQL 语句的注意事项
- SQL 语句不区分大小写
- 可以单行书写,也可以拆分为多行
- 关键字不能缩写、不能跨行拆分
- 推荐一个子句单独一行,增加可读性,适当缩进
- 结束符:
- SQL Developer:单条语句分号可省略;批量执行多条脚本必须加分号
; - SQL*Plus:每条 SQL 必须以分号
;结尾
- SQL Developer:单条语句分号可省略;批量执行多条脚本必须加分号
工具小区别:
- SQL*Plus:Oracle 原生命令行工具,执行 SQL、PL/SQL、管理脚本
- SQL Developer:图形化 IDE,开发、调试、管理一体,可视化更强
列头对齐规则:
- SQL Developer:字符标题默认左对齐,标题默认大写
- SQL*Plus:字符、日期列标题左对齐;数字列标题右对齐,标题默认大写
1.1.3 SELECT 语句中算术表达式和 NULL 值
1.1.3.1 算术表达式
支持数字、日期类型做四则运算,和数学运算优先级一致,括号可以改变优先级。
-- DUAL测试运算
SELECT 99*99 FROM DUAL;
SELECT (1+2)*3 FROM DUAL;
-- 表内字段运算:底薪+300
SELECT last_name, salary, salary + 300 FROM employees;
-- 不加括号:先乘后加
SELECT last_name, salary, 12*salary+100 FROM employees;
-- 加括号:先算加薪再乘以12
SELECT last_name, salary, 12*(salary+100) FROM employees;
1.1.3.2 NULL 空值
空值含义:未知、未分配、不适用的值。 ⚠️ NULL 不等于 0,也不等于空格。
-- 查看包含空值字段的数据(提成commission_pct很多员工为空)
SELECT last_name, job_id, salary, commission_pct FROM employees;
重点规则:任何数字和 NULL 做算术运算,结果一定是 NULL
-- 提成字段为NULL时,整行计算结果为NULL
SELECT last_name, 12*salary*commission_pct FROM employees;
后续可以用
NVL()函数处理 Oracle 空值,避免计算结果为空。
1.1.4 列别名
作用:给查询出来的列重命名,适合计算字段美化展示。 语法:列名后直接写别名,或者加 AS; 如果别名包含空格、特殊字符、需要区分大小写,必须使用双引号包裹(Oracle 单引号是字符串,双引号用来标记标识符,这点和 MySQL 不一样!)
-- AS简写,简单别名,不需要引号
SELECT last_name AS name, commission_pct comm FROM employees;
-- 别名带空格,大小写敏感,使用双引号
SELECT last_name "Name" , salary*12 "Annual Salary" FROM employees;
踩坑提醒:Oracle 单引号
' '代表字符串字面量,双引号" "用来标记列名、表名别名。
1.1.5 串联运算符,文字字符串,替代引号运算符和 DISTINCT 关键字
1.1.5.1 连接符 ||
Oracle 使用 || 做字符串拼接(MySQL 使用 CONCAT() 函数),把多个字段、文本拼接成一列返回。
-- 姓名:岗位
SELECT last_name||' : '||job_id AS "Employees" FROM employees;
-- 直接拼接姓名和岗位,中间无分隔
SELECT last_name || job_id AS "Employee Details" FROM employees;
1.1.5.2 文字字符串
字面常量:字符、数字、日期,字符和日期必须放在单引号里面,每行都会拼接这个文本。
SELECT last_name ||' is a '||job_id AS "Employee Details" FROM employees;
1.1.5.3 替代引号运算符 q'[]'
场景:字符串内部包含大量单引号,正常写法需要转义,非常麻烦。 q'[ 内容 ]' 自定义边界符,中括号里面的内容直接原样写,不需要转义单引号。
-- 原生写法,需要转义,可读性差
SELECT '''HELLO WORLD''' FROM DUAL;
-- q'[]' 替代引号,里面的单引号不用转义
SELECT department_name || q'[ Department's Manager Id: ]' || manager_id AS "Department and Manager"
FROM departments;
分隔符可以换:
q'{}'、q'()'都可以,成对即可。
1.1.5.4 DISTINCT 去重
默认查询会返回全部行,包含重复;加上 DISTINCT 对整行组合去重。
-- 不去重,会重复出现部门编号
SELECT department_id FROM employees;
-- 去重,每个部门编号只出现一次
SELECT DISTINCT department_id FROM employees;
1.1.5.5 查看表结构 DESCRIBE
DESC / DESCRIBE 查看表字段、类型、是否为空,SQL*Plus / SQL Developer 命令行可用,不是标准 SQL,是客户端命令。
-- 简写
DESC employees;
-- 全写,效果一致
DESCRIBE employees;