SQLite UNION 和 UNION ALL 详解及示例(七)

在处理数据库查询时,有时我们需要将多个 SELECT 语句的结果合并在一起。SQLite 提供了两种强大的工具来实现这一目标:UNION 和 UNION ALL。本文将详细介绍这两种子句的语法、用法以及注意事项,并通过具体示例帮助你更好地理解和应用这些功能。

UNION 子句

UNION 子句用于合并两个或多个 SELECT 语句的结果集,但会自动去除重复的行。使用 UNION 时,需要注意以下几点:

  1. 每个 SELECT 语句选择的列数必须相同。
  2. 列的数据类型必须匹配,并且顺序一致。
  3. 列的名称可以不同,但最终结果集的列名将采用第一个 SELECT 语句中的列名。

语法

UNION 的基本语法如下:

SELECT column1, column2, ...
FROM table1
[WHERE condition]

UNION

SELECT column1, column2, ...
FROM table2
[WHERE condition]

示例

假设我们有两个表:COMPANY 和 DEPARTMENT。COMPANY 表存储员工信息,DEPARTMENT 表存储部门信息。我们可以通过 UNION 来获取所有员工及其所在部门的信息。

表结构

-- COMPANY 表
sqlite> SELECT * FROM COMPANY;
ID          NAME                  AGE         ADDRESS     SALARY
----------  --------------------  ----------  ----------  ----------
1           Paul                  32          California  20000.0
2           Allen                 25          Texas       15000.0
3           Teddy                 23          Norway      20000.0
4           Mark                  25          Rich-Mond   65000.0
5           David                 27          Texas       85000.0
6           Kim                   22          South-Hall  45000.0
7           James                 24          Houston     10000.0

-- DEPARTMENT 表
sqlite> SELECT * FROM DEPARTMENT;
ID          DEPT                  EMP_ID
----------  --------------------  ----------
1           IT Billing            1
2           Engineering           2
3           Finance               7
4           Engineering           3
5           Finance               4
6           Engineering           5
7           Finance               6

查询示例

sqlite> SELECT EMP_ID, NAME, DEPT 
        FROM COMPANY INNER JOIN DEPARTMENT 
        ON COMPANY.ID = DEPARTMENT.EMP_ID

UNION

SELECT EMP_ID, NAME, DEPT 
FROM COMPANY LEFT OUTER JOIN DEPARTMENT 
ON COMPANY.ID = DEPARTMENT.EMP_ID;

执行上述查询后,结果如下:

EMP_ID      NAME                  DEPT
----------  --------------------  ----------
1           Paul                  IT Billing
2           Allen                 Engineering
3           Teddy                 Engineering
4           Mark                  Finance
5           David                 Engineering
6           Kim                   Finance
7           James                 Finance

UNION ALL 子句

UNION ALL 子句与 UNION 类似,但它不会去除重复的行。因此,UNION ALL 的性能通常比 UNION 更高,因为它不需要额外的去重操作。

语法

UNION ALL 的基本语法如下:

SELECT column1, column2, ...
FROM table1
[WHERE condition]

UNION ALL

SELECT column1, column2, ...
FROM table2
[WHERE condition]

示例

继续使用前面的 COMPANY 和 DEPARTMENT 表,我们可以通过 UNION ALL 来获取所有员工及其所在部门的信息,包括重复的行。

sqlite> SELECT EMP_ID, NAME, DEPT 
        FROM COMPANY INNER JOIN DEPARTMENT 
        ON COMPANY.ID = DEPARTMENT.EMP_ID

UNION ALL

SELECT EMP_ID, NAME, DEPT 
FROM COMPANY LEFT OUTER JOIN DEPARTMENT 
ON COMPANY.ID = DEPARTMENT.EMP_ID;

执行上述查询后,结果如下:

EMP_ID      NAME                  DEPT

----------  --------------------  ----------
1           Paul                  IT Billing
2           Allen                 Engineering
3           Teddy                 Engineering
4           Mark                  Finance
5           David                 Engineering
6           Kim                   Finance
7           James                 Finance
1           Paul                  IT Billing
2           Allen                 Engineering
3           Teddy                 Engineering
4           Mark                  Finance
5           David                 Engineering
6           Kim                   Finance
7           James                 Finance

NULL 值处理

在 SQLite 中,NULL 用于表示缺失的值。理解 NULL 值的处理方式对于编写准确的查询非常重要。

创建表时使用 NULL

在创建表时,可以指定某些列是否允许 NULL 值。例如:

CREATE TABLE COMPANY (
   ID INT PRIMARY KEY     NOT NULL,
   NAME           TEXT    NOT NULL,
   AGE            INT     NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL
);

在这个例子中,ID、NAME 和 AGE 列不允许 NULL 值,而 ADDRESS 和 SALARY 列允许 NULL 值。

处理 NULL 值

NULL 值在查询中可能会引起问题,因为与 NULL 值进行比较总是返回 NULL。例如,假设 COMPANY 表中有以下记录:

sqlite> SELECT * FROM COMPANY;
ID          NAME        AGE         ADDRESS     SALARY
----------  ----------  ----------  ----------  ----------
1           Paul        32          California  20000.0
2           Allen       25          Texas       15000.0
3           Teddy       23          Norway      20000.0
4           Mark        25          Rich-Mond   65000.0
5           David       27          Texas       85000.0
6           Kim         22
7           James       24

我们可以使用 UPDATE 语句将某些记录的 ADDRESS 和 SALARY 设置为 NULL:

sqlite> UPDATE COMPANY SET ADDRESS = NULL, SALARY = NULL WHERE ID IN (6, 7);

更新后的表如下:

ID          NAME        AGE         ADDRESS     SALARY
----------  ----------  ----------  ----------  ----------
1           Paul        32          California  20000.0
2           Allen       25          Texas       15000.0
3           Teddy       23          Norway      20000.0
4           Mark        25          Rich-Mond   65000.0
5           David       27          Texas       85000.0
6           Kim         22
7           James       24

使用 IS NULL 和 IS NOT NULL

可以使用 IS NULL 和 IS NOT NULL 运算符来筛选包含或不包含 NULL 值的记录。

筛选不包含 NULL 值的记录

sqlite> SELECT ID, NAME, AGE, ADDRESS, SALARY 
        FROM COMPANY 
        WHERE SALARY IS NOT NULL;

结果如下:

ID          NAME        AGE         ADDRESS     SALARY
----------  ----------  ----------  ----------  ----------
1           Paul        32          California  20000.0
2           Allen       25          Texas       15000.0
3           Teddy       23          Norway      20000.0
4           Mark        25          Rich-Mond   65000.0
5           David       27          Texas       85000.0

筛选包含 NULL 值的记录

sqlite> SELECT ID, NAME, AGE, ADDRESS, SALARY 
        FROM COMPANY 

        WHERE SALARY IS NULL;

结果如下:

ID          NAME        AGE         ADDRESS     SALARY
----------  ----------  ----------  ----------  ----------
6           Kim         22
7           James       24

表和列别名

在复杂的查询中,使用表和列别名可以提高代码的可读性和简洁性。

表别名

表别名用于在特定的查询中临时重命名表。语法如下:

SELECT column1, column2, ...
FROM table_name AS alias_name
WHERE [condition];

列别名

列别名用于在特定的查询中临时重命名列。语法如下:

SELECT column_name AS alias_name
FROM table_name
WHERE [condition];

示例

假设我们有两个表:COMPANY 和 DEPARTMENT。我们可以通过表别名来简化查询。

sqlite> SELECT C.ID, C.NAME, C.AGE, D.DEPT 
        FROM COMPANY AS C, DEPARTMENT AS D 
        WHERE C.ID = D.EMP_ID;

执行上述查询后,结果如下:

ID          NAME        AGE         DEPT
----------  ----------  ----------  ----------
1           Paul        32          IT Billing
2           Allen       25          Engineering
3           Teddy       23          Engineering
4           Mark        25          Finance
5           David       27          Engineering
6           Kim         22          Finance
7           James       24          Finance

总结

本文详细介绍了 SQLite 中的 UNION 和 UNION ALL 子句,包括它们的语法、用法和注意事项。同时,我们也探讨了 NULL 值的处理方法以及表和列别名的使用技巧。通过这些内容,你可以更灵活地处理和查询数据库中的数据,提升开发效率。希望本文对你有所帮助!