LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

分类介绍常用SQL表达式在SQL语句中的作用

admin
2026年2月17日 8:8 本文热度 279

在SQL中,我们经常碰到SQL语句、表达式和函数这三个概念。可能是熟视无睹,没有见谁仔细剖析过它们的关系。今天借这个机会,我们首先通过SQL表达式的概念来简单理清它们三者的关系。SQL语句包含表达式,SQL表达式是组成全部或部分SQL语句的字符串,是用在SQL语句中对数据进行操作、计算或条件判断的组合式语句,由常量、列名、运算符、函数等元素组成(由此可见,表达式可包含函数,函数可以是表达式的一部分),可用在查询过滤、数据转换、聚合计算等场景。下面,我们详细拆解SQL表达式,但只作备忘,不深入探讨。

SQL表达式的基本结构为:元素1 运算符 元素2 [运算符 元素3 ...]

  • 元素:可以是常量(如:100'abc')、列名(如:agename)、函数(如:SUM(score)CASE...END)。
  • 运算符:包括比较运算符(=><)、逻辑运算符(ANDOR)、算术运算符(+-)等等。

在按功能分类介绍常见SQL表达式之前,创建模拟学生表students,结构及数据如下:

id
name
age
score
sex
1
Alice
18
90
2
2
Bob
19
85
1
3
Charlie
17
NULL
1
4
David
18
95
1
5
Eve
19
88
2

一、基础运算表达式

对数据进行基础的数值计算、字符串处理或逻辑判断,我们称它是SQL中最常用的表达式类型。

1、算术表达式

对数值型数据进行计算,支持基本算术运算(+-*/%)。
(1)基础算术运算

  • 示例1:计算每个学生的分数加5分后的成绩

    SELECT name, score, score + 5 AS 调整后分数 FROM students;

    结果输出

    name
    score
    调整后分数
    Alice
    90
    95
    Bob
    85
    90
    Charlie
    NULL
    NULL
    David
    95
    100
    Eve
    88
    93
  • 示例2:计算年龄与分数的差值(年龄 - 分数)

    SELECT name, age, score, age - score AS 年龄分数差 FROM students;

    结果输出

    name
    age
    score
    年龄分数差
    Alice
    18
    90
    -72
    Bob
    19
    85
    -66
    Charlie
    17
    NULL
    NULL
    David
    18
    95
    -77
    Eve
    19
    88
    -69

(2)复合算术表达式

  • 示例:计算加权分数(假设权重为:年龄占比20%,分数占比80%)
    SELECT name, age, score, age * 0.2 + score * 0.8 AS 加权分数 FROM students;
    结果输出
    name
    age
    score
    加权分数
    Alice
    18
    90
    75.6
    Bob
    19
    85
    71.8
    Charlie
    17
    NULL
    NULL
    David
    18
    95
    79.6
    Eve
    19
    88
    74.2
2、字符串表达式

用在字符串的拼接、截取、转换等操作。

(1)字符串拼接

  • 示例1:拼接姓名和性别描述

    SELECT name, sex, CONCAT(name, '的性别是', CASE sex WHEN '1' THEN '男' WHEN '2' THEN '女' ELSE '其他' END) AS 描述 FROM students;

    结果输出

    name
    sex
    描述
    Alice
    2
    Alice的性别是女
    Bob
    1
    Bob的性别是男
    Charlie
    1
    Charlie的性别是男
    David
    1
    David的性别是男
    Eve
    2
    Eve的性别是女
  • 示例2:使用||拼接(部分数据库支持,如:PostgreSQL、Oracle)

    SELECT name || '的分数是' || score AS 分数描述 FROM students WHERE score IS NOT NULL;

    结果输出

    分数描述
    Alice的分数是90
    Bob的分数是85
    David的分数是95
    Eve的分数是88

(2)字符串函数

  • 示例1:截取姓名的前两个字符
    SELECT name, LEFT(name, 2) AS 姓名缩写 FROM students;
    结果输出
    name
    姓名缩写
    Alice
    Al
    Bob
    Bo
    Charlie
    Ch
    David
    Da
    Eve
    Ev
  • 示例2:转换字符串大小写
    SELECT name, UPPER(name) AS 大写姓名, LOWER(name) AS 小写姓名 FROM students;
    结果输出
    name
    大写姓名
    小写姓名
    Alice
    ALICE
    alice
    Bob
    BOB
    bob
    Charlie
    CHARLIE
    charlie
    David
    DAVID
    david
    Eve
    EVE
    eve
3、条件表达式

判断数据是否满足指定条件,返回布尔值(TRUE/FALSE)。

(1)简单条件表达式
通过比较运算符(=><>=<=!=)比较两个值或表达式。

  • 示例1:查询年龄大于18岁的学生

    SELECT name, age FROM students WHERE age > 18;

    结果输出

    name
    age
    Bob
    19
    Eve
    19
  • 示例2:查询分数不等于90的学生

    SELECT name, score FROM students WHERE score != 90;

    结果输出

    name
    score
    Bob
    85
    David
    95
    Eve
    88

(2)逻辑条件表达式
使用ANDORNOT组合多个条件。

  • 示例1:查询年龄18岁且分数大于85的学生

    SELECT name, age, score FROM students WHERE age = 18 AND score > 85;

    结果输出

    name
    age
    score
    Alice
    18
    90
    David
    18
    95
  • 示例2:查询性别为1(男)或分数大于90的学生

    SELECT name, sex, score FROM students WHERE sex = 1 OR score > 90;

    结果输出

    name
    sex
    score
    Bob
    1
    85
    Charlie
    1
    NULL
    David
    1
    95

    注:David性别为1、分数95,Bob、Charlie性别为1

二、数据查询与匹配表达式

在查询中筛选符合特定模式或范围的数据,扩展基础条件判断的能力。

1、模糊查询表达式

匹配符合特定模式的数据,无需精确相等。

(1)LIKE表达式

  • %:匹配任意数量字符(包括0个);_:匹配单个字符。

  • 示例1:查询名字以A开头的学生

    SELECT name FROM students WHERE name LIKE 'A%';

    结果输出

    name
    Alice
  • 示例2:查询名字第二个字符是o的学生

    SELECT name FROM students WHERE name LIKE '_o%';

    结果输出

    name
    Bob

(2)IN表达式
判断值是否在指定集合中。

  • 示例:查询年龄为17或19的学生
    SELECT name, age FROM students WHERE age IN (17, 19);
    结果输出
    name
    age
    Bob
    19
    Charlie
    17
    Eve
    19
2、正则表达式(RLIKE)

通过正则模式匹配数据,RLIKE(或REGEXP)指定匹配规则。

  • 示例:查询名字以AD开头的学生

    SELECT name FROM students WHERE name RLIKE '^[AD]';

    结果输出

    name
    Alice
    David

    注:^[AD]表示以AD开头的字符串

3、全文本搜索表达式

实现语义化文本搜索(匹配度比LIKE模式高),适用大文本字段检索。

(1)MATCH AGAINST(MySQL)

-- 建立全文索引
ALTER TABLE students ADD FULLTEXT(name); 

-- 布尔模式搜索
SELECT * FROM students 
WHERE MATCH(name) AGAINST('+David -Alice' IN BOOLEAN MODE);

结果输出

id
name
age
score
sex
4
David
18
95
1

(2)TSVECTOR(PostgreSQL)

SELECT * FROM students 
WHERE to_tsvector('english', name) @@ to_tsquery('english''David & !Alice');

优势对比

搜索方式
搜索语句
匹配结果
LIKE
WHERE name LIKE '%Dav%'
David
全文检索
AGAINST('David')
David, Davies

三、数据统计与分析表达式

对数据进行聚合计算、分组分析或复杂统计,适用数据分析场景。

1、聚合函数表达式

对一列数据进行统计计算,返回单个结果。

(1)COUNT函数
统计记录或非NULL值的数量。

  • 示例1:统计学生总数

    SELECT COUNT(*) AS 总人数 FROM students;

    结果输出

    总人数
    5
  • 示例2:统计分数非NULL的学生数

    SELECT COUNT(score) AS 有分数的人数 FROM students;

    结果输出

    有分数的人数
    4

    注:Charlie的score为NULL,不统计

(2)SUM函数
计算列的总和(仅适用于数值型)。

  • 示例:计算所有学生的分数总和

    SELECT SUM(score) AS 总分 FROM students;

    结果输出

    总分
    358

    注:90+85+95+88=358,忽略NULL

(3)AVG函数
计算列的平均值(仅适用于数值型)。

  • 示例:计算分数的平均值

    SELECT AVG(score) AS 平均分 FROM students;

    结果输出

    平均分
    89.5

    注:358÷4=89.5,AVG函数自动忽略NULL值,因此计算结果基于4条有效分数记录

2、窗口函数表达式

在结果集的分区或排序范围内进行计算(如:排名、移动平均等)。

(1)排名函数

  • 示例1:按分数排名(相同分数并列)

    SELECT name, score, RANK() OVER (ORDER BY score DESC) AS 分数排名 FROM students;

    结果输出

    name
    score
    分数排名
    David
    95
    1
    Alice
    90
    2
    Eve
    88
    3
    Bob
    85
    4
    Charlie
    NULL
    5
  • 示例2:按年龄分组后排名

    SELECT name, age, score, RANK() OVER (PARTITION BY age ORDER BY score DESC) AS 年龄内排名 FROM students;

    结果输出

    name
    age
    score
    年龄内排名
    Alice
    18
    90
    2
    David
    18
    95
    1
    Bob
    19
    85
    2
    Eve
    19
    88
    1
    Charlie
    17
    NULL
    1

(2)聚合窗口函数

  • 示例:计算每个学生的分数与平均分的差值
    SELECT name, score, AVG(score) OVER () AS 全体平均分, score - AVG(score) OVER () AS 与平均分差值 FROM students;
    结果输出
    name
    score
    全体平均分
    与平均分差值
    Alice
    90
    89.5
    0.5
    Bob
    85
    89.5
    -4.5
    Charlie
    NULL
    89.5
    NULL
    David
    95
    89.5
    5.5
    Eve
    88
    89.5
    -1.5

(3)窗口函数增强表达式
在基础窗口函数上,结合RANGEGROUPS等实现更灵活的窗口定义。

① RANGE与GROUPS区别

  • RANGE:基于值范围(如:前后10分)。
  • GROUPS:基于行数范围(如:前5行)。
    示例:计算每个学生分数与前一名学生的分数差(RANGE)
    SELECT 
        name,
        score,
        score - LAG(score, 1) OVER (ORDER BY score) AS 分数差
    FROM students;
    结果输出
    name
    score
    分数差
    Bob
    85
    NULL
    Eve
    88
    3
    Alice
    90
    2
    David
    95
    5
    Charlie
    NULL
    NULL

② 自定义窗口帧
明确指定窗口的起始和结束范围。

示例:计算每个学生及其后两名学生的平均分

SELECT 
    name,
    score,
    AVG(score) OVER (
        ORDER BY score 
        ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING
    ) AS 三人平均分
FROM students;

结果输出

name
score
三人平均分
计算式
Bob
85
87.67
(85+88+90)/3
Eve
88
91
(88+90+95)/3
Alice
90
92.5
(90+95)/2
David
95
95
95/1
Charlie
NULL
NULL

3、分组聚合表达式

结合GROUP BY对数据分组后进行聚合计算,实现分类统计。

  • 示例1:按性别分组统计平均分

    SELECT sex, AVG(score) AS 性别平均分 FROM students GROUP BY sex;

    结果输出

    sex
    性别平均分
    计算式
    1
    90
    (Bob85 + David95 = 180 ÷ 2)
    2
    89
    (Alice90 + Eve88 = 178 ÷ 2)
  • 示例2:使用HAVING筛选分组结果(筛选平均分≥89的性别)

    SELECT sex, AVG(score) AS 性别平均分 
    FROM students 
    GROUP BY sex 
    HAVING AVG(score) >= 89;

    结果输出

    sex
    性别平均分
    1
    90
    2
    89
4、条件聚合表达式

在聚合函数中嵌套条件判断,实现“按条件统计”,无需额外GROUP BY或子查询。

  • 示例1:分别统计男生和女生的平均分(一行展示多维度聚合结果)

    SELECT 
        AVG(CASE WHEN sex = 1 THEN score END) AS 男生平均分,
        AVG(CASE WHEN sex = 2 THEN score END) AS 女生平均分
    FROM students;
  • 示例2:统计不同分数段的人数

    SELECT 
        COUNT(CASE WHEN score >= 90 THEN 1 END) AS 优秀人数,
        COUNT(CASE WHEN score BETWEEN 80 AND 89 THEN 1 END) AS 良好人数,
        COUNT(CASE WHEN score < 80 THEN 1 END) AS 待提升人数
    FROM students;
5、分组聚合增强表达式

在基础分组聚合的基础上,通过ROLLUPCUBE等扩展实现多维度汇总,或使用GROUPING SETS自定义分组组合。

(1)ROLLUP表达式
生成从细粒度到粗粒度的层次化汇总结果(如:按年级、学院、学校汇总)。

示例:按年龄分组并计算总分,同时生成年龄为NULL的总体汇总

SELECT 
    age, 
    SUM(score) AS 总分 
FROM students 
GROUP BY ROLLUP(age);

结果输出

age
总分
说明
17
NULL

18
185
90+95
19
173
85+88
NULL
358
总体汇总

(2)CUBE表达式
生成所有可能的分组组合(如:按年龄、性别、年龄+性别分组)。

示例:按年龄和性别分组计算平均分,并生成所有子组合

SELECT 
    age, 
    sex, 
    AVG(score) AS 平均分 
FROM students 
GROUP BY CUBE(age, sex);

结果输出

age
sex
平均分
说明
17
1
NULL

18
1
95

18
2
90

19
1
85

19
2
88

NULL
NULL
89.5
总体平均
NULL
1
90
男性平均
NULL
2
89
女性平均
17
NULL
NULL

18
NULL
92.5
18岁平均
19
NULL
86.5
19岁平均

(3)GROUPING SETS表达式
自定义分组组合,避免生成所有可能的组合。

示例:仅按年龄和性别分组,不生成交叉组合

SELECT 
    age, 
    sex, 
    COUNT(*) AS 人数 
FROM students 
GROUP BY GROUPING SETS(age, sex);

结果输出

age
sex
人数
17
NULL
1
18
NULL
2
19
NULL
2
NULL
1
3
NULL
2
2

6、数据分桶表达式

将连续数值离散化为区间,适用于分布分析和等级划分。

(1)WIDTH_BUCKET函数(部分DB支持)

  • 示例:将分数均匀分入5个桶
-- PostgreSQL/Oracle语法
SELECT 
  WIDTH_BUCKET(score, 0, 100, 5) AS bucket,  -- 0-100分分5桶(每桶20分)
  COUNT(*) AS 人数
FROM students
WHERE score IS NOT NULL  -- 排除NULL值
GROUP BY bucket;

结果输出

bucket
人数
分数范围
5
4
[80,100]

注:85、88、90、95在此区间

(2)通用分桶方案

  • 示例:用CASE实现自定义分桶
    SELECT 
      CASE
        WHEN score >= 90 THEN 'A'
        WHEN score >= 80 THEN 'B'
        ELSE 'C'
      END AS grade_level,
      COUNT(*) AS 人数
    FROM students
    GROUP BY grade_level;
    结果输出
    grade_level
    人数
    A
    2
    B
    2
    C
    1

四、数据转换与处理表达式

对数据类型进行转换、处理特殊值(如:NULL)或实现多条件分支判断。

1、CASE表达式

多条件判断,实现数据转换或分类。

(1)简单CASE表达式
语法:CASE 列名 WHEN 匹配值 THEN 结果1 [WHEN 匹配值2 THEN 结果2 ... ELSE 默认结果 END]

  • 示例:将性别编码转换为文字
    SELECT name, CASE sex WHEN '1' THEN '男' WHEN '2' THEN '女' ELSE '其他' END AS 性别 FROM students;
    结果输出
    name
    性别
    Alice
    Bob
    Charlie
    David
    Eve

(2)搜索CASE表达式
语法:CASE WHEN 条件1 THEN 结果1 [WHEN 条件2 THEN 结果2 ... ELSE 默认结果 END]

  • 示例:根据分数划分等级
    SELECT name, score, CASE WHEN score >= 90 THEN '优秀' WHEN score >= 80 THEN '良好' ELSE '待提升' END AS 等级 FROM students;
    结果输出
    name
    score
    等级
    Alice
    90
    优秀
    Bob
    85
    良好
    Charlie
    NULL
    待提升
    David
    95
    优秀
    Eve
    88
    良好
2、转换表达式

用在数据类型转换(如:字符串转数值、日期转字符串等)。

(1)显式类型转换

  • 示例1:将字符串转换为数值

    SELECT '100' + 50 AS 结果;  -- 部分数据库会自动转换,或使用CAST

    使用CAST的写法:

    SELECT CAST('100' AS INT) + 50 AS 结果;

    结果输出

    结果
    150
  • 示例2:将数值转换为字符串

    SELECT CONCAT('分数为', CAST(score AS VARCHAR)) AS 分数描述 FROM students;

    结果输出

    分数描述
    分数为90
    分数为85
    分数为NULL
    分数为95
    分数为88

(2)日期与字符串转换

  • 示例:将日期字符串转换为日期类型
    SELECT CAST('2025-07-30' AS DATE) AS 日期类型;
    结果输出
    日期类型
    2025-07-30
3、NULL处理表达式
  • 示例1:使用COALESCE替换NULL值

    SELECT name, score, COALESCE(score, 0) AS 替换后分数 FROM students;

    结果输出

    name
    score
    替换后分数
    Alice
    90
    90
    Bob
    85
    85
    Charlie
    NULL
    0
    David
    95
    95
    Eve
    88
    88
  • 示例2:使用IFNULL(MySQL语法)或ISNULL(SQL Server语法)

    SELECT name, IFNULL(score, 0) AS 替换后分数 FROM students;

    结果输出:同COALESCE示例。

4、空值安全表达式

专为NULL比较设计,解决常规运算符无法处理NULL的问题(如:a=NULL始终返回NULL)。

(1)空值安全等于

  • MySQL<=>运算符
    SELECT * FROM students WHERE score <=> NULL;  -- 准确检索NULL值
    结果输出
    id
    name
    age
    score
    sex
    3
    Charlie
    17
    NULL
    1

(2)IS DISTINCT FROM

  • PostgreSQL/SQL标准:替代!=的安全比较
    SELECT * FROM students WHERE score IS DISTINCT FROM 90; -- 包含对NULL的处理
    结果输出
    id
    name
    age
    score
    sex
    2
    Bob
    19
    85
    1
    3
    Charlie
    17
    NULL
    1
    4
    David
    18
    95
    1
    5
    Eve
    19
    88
    2
5、条件赋值表达式

使用IF函数(MySQL)或IIF函数(SQL Server)进行简单条件判断。

  • 示例:用IF函数标记分数是否及格(假设60分为及格线)

    SELECT name, score, IF(score >= 60, '及格''不及格') AS 及格状态 FROM students;

    结果输出

    name
    score
    及格状态
    Alice
    90
    及格
    Charlie
    NULL
    不及格

    注:NULL视为不及格

6、条件赋值增强表达式

在基础CASEIF的基础上,通过嵌套或复杂逻辑实现多级条件判断。

(1)嵌套CASE表达式
THENELSE子句中嵌套多层CASE
示例:根据分数和年龄划分奖学金等级

SELECT 
    name, 
    age, 
    score,
    CASE 
        WHEN score >= 95 THEN '一等奖'
        WHEN score >= 90 THEN 
            CASE 
                WHEN age < 18 THEN '二等奖(年龄加分)'
                ELSE '二等奖'
            END
        ELSE '无'
    END AS 奖学金等级
FROM students;

结果输出

name
age
score
奖学金等级
Alice
18
90
二等奖
Bob
19
85
Charlie
17
NULL
David
18
95
一等奖
Eve
19
88

(2)动态条件赋值
结合子查询或变量实现条件结果的动态生成。

示例:根据班级平均分动态调整学生评级

SELECT 
    name, 
    score,
    CASE 
        WHEN score >= (SELECT AVG(score) FROM students) + 10 THEN '优秀'
        WHEN score >= (SELECT AVG(score) FROM students) THEN '良好'
        ELSE '待提升'
    END AS 动态评级
FROM students;

结果输出

name
score
动态评级
Alice
90
良好
Bob
85
待提升
Charlie
NULL
待提升
David
95
优秀
Eve
88
待提升

五、数据校验与约束表达式

在数据插入、更新时进行合法性校验,或在查询中过滤无效数据,常见于CHECK约束、数据清洗场景。

1、约束校验表达式

通过CHECK约束在表结构定义时限制列的取值范围,确保数据合法性(部分数据库如:PostgreSQL、MySQL 8.0+支持)。

  • 示例:创建学生表时限制年龄在10-30岁之间
    CREATE TABLE students (
        id INT,
        name VARCHAR(50),
        age INT CHECK (age BETWEEN 10 AND 30), -- 年龄范围约束
        score INT CHECK (score >= 0 AND score <= 100) -- 分数范围约束
    );
    当插入age=35的记录时,会因违反CHECK约束而失败。
2、数据清洗表达式

在查询或ETL过程中过滤或修正无效数据,结合CASEREGEXP等实现。

  • 示例:清洗手机号格式(仅保留11位数字,其他标记为无效)
    SELECT 
        user_id,
        phone,
        CASE 
            WHEN phone REGEXP '^1[3-9][0-9]{9}$' THEN phone 
            ELSE '无效手机号' 
        END AS 清洗后手机号
    FROM user_info;

六、高级查询与集合表达式

构建复杂查询逻辑,将查询结果作为其他操作的输入或数据源。

1、子查询表达式

将查询结果作为表达式的一部分,用在主查询的条件、计算或数据源。

(1)标量子查询

  • 示例:查询分数高于平均分的学生
-- 平均分89.5,分数高于平均分的学生为Alice(90)和David(95)
SELECT name, score FROM students WHERE score > (SELECT AVG(score) FROM students);

结果输出

name
score
Alice
90
David
95

(2)关联子查询

  • 示例:查询每个年龄段中分数最高的学生
    SELECT s1.name, s1.age, s1.score 
    FROM students s1 
    WHERE score = (SELECT MAX(score) FROM students s2 WHERE s2.age = s1.age);
    结果输出
    name
    age
    score
    David
    18
    95
    Eve
    19
    88
    Charlie
    17
    NULL
2、变量表达式
  • 示例:使用会话变量存储计算结果
    SET @avg_score = (SELECT AVG(score) FROM students);
    SELECT name, score, @avg_score AS 全体平均分 FROM students;
    结果输出
    name
    score
    全体平均分
    Alice
    90
    89.5
    Bob
    85
    89.5
    Charlie
    NULL
    89.5
    David
    95
    89.5
    Eve
    88
    89.5
3、集合操作表达式

对多个查询结果集进行合并、交集或差集运算,适用于多表或多条件下的结果整合。

(1)UNION与UNION ALL

  • UNION:合并两个结果集并去除重复记录(要求列数和数据类型一致)。

    示例:查询年龄18岁的学生和分数大于90的学生(去重)

    SELECT name, age, score FROM students WHERE age = 18
    UNION
    SELECT name, age, score FROM students WHERE score > 90;

    结果输出

    name
    age
    score
    Alice
    18
    90
    David
    18
    95

    注:David同时满足两个条件,但仅显示一次

  • UNION ALL:合并两个结果集但保留重复记录。
    示例:同上,但保留重复项

    SELECT name, age, score FROM students WHERE age = 18
    UNION ALL
    SELECT name, age, score FROM students WHERE score > 90;

    结果输出

    name
    age
    score
    Alice
    18
    90
    David
    18
    95
    David
    18
    95

    注:David重复出现

(2)INTERSECT(交集)
返回两个结果集的共有记录(部分数据库支持,如:PostgreSQL、Oracle)。

示例:查询年龄18岁且分数大于90的学生(等价于AND,但适用于多表场景)

SELECT name, age, score FROM students WHERE age = 18
INTERSECT
SELECT name, age, score FROM students WHERE score > 90;

结果输出

name
age
score
David
18
95

(3)EXCEPT(差集)
返回第一个结果集独有的记录(部分数据库支持)。

示例:查询年龄18岁但分数不大于90的学生

SELECT name, age, score FROM students WHERE age = 18
EXCEPT
SELECT name, age, score FROM students WHERE score > 90;

结果输出

name
age
score
Alice
18
90

4、序列生成表达式

动态生成数字/日期序列,适用于补全缺失数据、生成测试数据等场景。

(1)GENERATE_SERIES函数

  • PostgreSQL示例:生成连续数字序列
    SELECT generate_series(1,5) AS id; -- 生成1-5的整数
    结果输出
    id
    1
    2
    3
    4
    5

(2)递归CTE生成

  • 跨数据库方案
    WITH RECURSIVE seq AS (
      SELECT 1 AS n
      UNION ALL
      SELECT n+1 FROM seq WHERE n<5
    ) SELECT * FROM seq;
    结果输出:同GENERATE_SERIES示例

(3)日期序列

  • 示例:生成7天日期序列
    SELECT generate_series(
      CURRENT_DATE, 
      CURRENT_DATE + INTERVAL '6 days'
      '1 day'
    ) AS day;

5、递归查询表达式

通过递归CTE(Common Table Expression)实现层次化数据查询(如:组织架构、多级分类)。

(1)简单递归查询
查询员工及其所有上级(假设employees表包含idnamemanager_id)。

示例:查询员工"Bob"的所有上级

WITH RECURSIVE subordinates AS (
    SELECT id, name, manager_id
    FROM employees
    WHERE name = 'Bob'
    UNION ALL
    SELECT e.id, e.name, e.manager_id
    FROM employees e
    JOIN subordinates s ON e.id = s.manager_id
)
SELECT * FROM subordinates;

结果输出

id
name
manager_id
2
Bob
1
1
Alice
NULL

(2)递归聚合计算
计算层次化数据的聚合值(如:部门总薪资)。

示例:计算每个部门及其子部门的总薪资

WITH RECURSIVE dept_hierarchy AS (
    SELECT id, name, parent_id, salary
    FROM departments
    WHERE parent_id IS NULL
    UNION ALL
    SELECT d.id, d.name, d.parent_id, d.salary
    FROM departments d
    JOIN dept_hierarchy dh ON d.parent_id = dh.id
)
SELECT 
    name,
    SUM(salary) AS 总薪资
FROM dept_hierarchy
GROUP BY name;

七、日期与时间表达式

用在日期和时间的计算、格式化等操作。

1、日期函数
  • 示例1:提取当前日期(假设当前日期为2025-07-30

    SELECT CURRENT_DATE AS 当前日期;

    结果输出

    当前日期
    2025-07-30
  • 示例2:计算出生日期(假设students表添加birth_date列)

    SELECT name, birth_date, DATEDIFF(CURRENT_DATE, birth_date) AS 年龄天数 FROM students;

    结果输出(示例数据):

    name
    birth_date
    出生至今的总天数
    Alice
    2007-07-30
    6570
    Bob
    2006-07-30
    6935
    Charlie
    2008-07-30
    6205
    David
    2007-07-30
    6570
    Eve
    2006-07-30
    6935
2、日期格式化
  • 示例:格式化日期显示
    SELECT CURRENT_DATE AS 原始日期, DATE_FORMAT(CURRENT_DATE, '%Y年%m月%d日') AS 格式化日期;
    结果输出
    原始日期
    格式化日期
    2025-07-30
    2025年07月30日
3、日期增减计算

通过DATE_ADD(MySQL)或DATEADD(SQL Server)对日期进行加减。

  • 示例1:计算30天后的日期

    SELECT CURRENT_DATE AS 当前日期, DATE_ADD(CURRENT_DATE, INTERVAL 30 DAY) AS 30天后 FROM students LIMIT 1;

    结果输出

    当前日期
    30天后
    2025-07-30
    2025-08-29
  • 示例2:计算学生出生年份(假设年龄字段为age

    SELECT name, age, YEAR(CURRENT_DATE) - age AS 出生年份 FROM students;

    结果输出

    name
    age
    出生年份
    Alice
    18
    2007
    Bob
    19
    2006
4、日期计算增强表达式

在基础日期函数上,结合EXTRACTTIMESTAMPDIFF等实现更灵活的日期分析。

(1)EXTRACT函数
提取日期的特定部分(年、月、日、小时等)。

示例:提取学生的出生月份并统计各月出生人数

SELECT 
    EXTRACT(MONTH FROM birth_date) AS 月份,
    COUNT(*) AS 人数
FROM students
GROUP BY EXTRACT(MONTH FROM birth_date);

结果输出(假设所有学生出生月份相同):

月份
人数
7
5

(2)时间差计算
计算两个日期之间的精确差值(年、月、日、小时等)。
示例:计算学生年龄精确到月

SELECT 
    name,
    age,
    TIMESTAMPDIFF(YEAR, birth_date, CURRENT_DATE) AS 按年计算年龄,
    TIMESTAMPDIFF(MONTH, birth_date, CURRENT_DATE) AS 按月计算年龄
FROM students;

结果输出

name
age
按年计算年龄
按月计算年龄
Alice
18
18
216
Bob
19
19
228

(3)日期区间判断
判断日期是否在指定范围内。

示例:查询出生日期在2006-2008年之间的学生

SELECT 
    name,
    birth_date
FROM students
WHERE birth_date BETWEEN '2006-01-01' AND '2008-12-31';

结果输出

name
birth_date
Bob
2006-07-30
Charlie
2008-07-30
Eve
2006-07-30

八、特殊场景表达式

1、位运算表达式

对整数进行二进制位级别的操作,适用于权限控制、状态标记等场景(部分数据库支持)。

(1)基础位运算

  • 按位与(&):两个位都为1则结果为1。
    示例:判断性别编码(1或2)的二进制最低位是否为1(1的二进制为01,2为10
-- 二进制最低位判断(1的二进制为01,2为10)
SELECT name, sex, sex & 1 AS 二进制最低位 FROM students;

结果输出

name
sex
二进制最低位
Alice
2
0
Bob
1
1

  • 按位或(|):两个位有一个为1则结果为1。
    示例:将性别编码与3(二进制11)进行按位或
    SELECT name, sex, sex | 3 AS 结果 FROM students;
    结果输出
    name
    sex
    结果
    Alice
    2
    3
    Bob
    1
    3
2、JSON表达式(部分数据库支持)

直接操作JSON数据,适用于半结构化数据存储场景。

(1)JSON提取函数
从JSON字段中提取指定值。

示例:假设students表包含info列(JSON类型),提取学生的爱好

-- PostgreSQL语法
SELECT name, info -> '$.hobbies' AS 爱好 FROM students;

-- MySQL语法(需使用JSON_EXTRACT函数)
SELECT name, JSON_EXTRACT(info, '$.hobbies') AS 爱好 FROM students;

结果输出(示例JSON数据):

name
爱好
Alice
["reading", "music"]
Bob
["sports"]

(2)JSON生成函数
将普通数据转换为JSON格式。

示例:将学生信息生成JSON字符串

SELECT 
    name,
    age,
    JSON_OBJECT('name', name, 'age', age, 'score', score) AS 学生信息
FROM students;

结果输出

name
age
学生信息
Alice
18
{"name": "Alice", "age": 18, "score": 90}

(3)JSON修改函数
更新JSON字段的值。

示例:更新学生的爱好(PostgreSQL语法)

UPDATE students
SET info = jsonb_set(info, '{hobbies}''["reading", "music", "coding"]')
WHERE name = 'Alice';
3、数组与集合操作表达式(部分数据库支持)

针对数组类型数据的操作,适用于存储多值字段(如:标签、权限列表),常见于PostgreSQL、Oracle等。

(1)数组创建与访问

  • 示例1:创建包含多门课程的数组字段

    SELECT 
        name,
        ARRAY['数学''英语''物理'] AS 课程列表
    FROM students;
  • 示例2:访问数组中的元素(下标从1开始)

    SELECT 
        name,
        课程列表[2] AS 第二门课程 -- 获取数组中第二个元素
    FROM (
        SELECT name, ARRAY['数学''英语''物理'] AS 课程列表 FROM students
    ) AS sub;

(2)数组函数

  • 示例:判断数组是否包含某个元素
    SELECT 
        name,
        课程列表,
        '英语' = ANY(课程列表) AS 是否包含英语
    FROM (
        SELECT name, ARRAY['数学''英语''物理'] AS 课程列表 FROM students
    ) AS sub;
4、地理空间表达式(PostGIS等扩展)

处理地理空间数据,如:计算距离、判断包含关系等。

(1)距离计算
计算两点之间的距离(单位:米)。

示例:查询距离"Point(116.4 39.9)"10公里内的学生

SELECT 
    name,
    ST_Distance(location::geography, 'POINT(116.4 39.9)'::geography) AS 距离
FROM students
WHERE ST_DWithin(location::geography, 'POINT(116.4 39.9)'::geography, 10000);

(2)空间关系判断
判断地理对象是否包含或相交。

示例:查询位于"Polygon"区域内的学生

SELECT 
    name
FROM students
WHERE ST_Contains('POLYGON((...))'::geometry, location::geometry);

综上所述,SQL表达式是SQL语句的重要部分,各种数据处理的应用场景,从基础运算、数据查询与匹配、数据统计与分析、数据转换与处理……到JSON操作、地理空间计算等等,它都能轻松应对。不同类型的SQL表达式各有其适用场景,我们合理运用它能明显提升SQL查询的效率和功能性。我们通过灵活组合这些表达式,可以实现复杂的多样化的数据查询、转换和分析需求。


阅读原文:原文链接


该文章在 2026/2/22 23:29:59 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2026 ClickSun All Rights Reserved