SQLite Unions 子句

SQLite 的 UNION 子句 用于将多个 SELECT 查询的结果合并成一个结果集,自动去重。常用于:

  • 合并多个表的数据
  • 分表查询汇总
  • 替代复杂 OR 条件

基本语法

SELECT column1, column2, ... FROM table1
[WHERE ...]
UNION
SELECT column1, column2, ... FROM table2
[WHERE ...]
[ORDER BY ...]
[LIMIT ...];
  • 每个 SELECT列数必须相同
  • 列的数据类型应兼容
  • 默认去除重复行(全结果集去重)

UNION vs UNION ALL

操作符去重性能使用场景
UNION较慢需要唯一结果
UNION ALL更快允许重复,推荐

示例表结构

-- 2024 年订单表
CREATE TABLE orders_2024 (
    order_id INTEGER PRIMARY KEY,
    user_id INTEGER,
    product TEXT,
    amount REAL,
    order_date DATE
);

-- 2025 年订单表
CREATE TABLE orders_2025 (
    order_id INTEGER PRIMARY KEY,
    user_id INTEGER,
    product TEXT,
    amount REAL,
    order_date DATE
);

-- 插入数据
INSERT INTO orders_2024 VALUES
(1, 101, 'Laptop', 1200, '2024-06-15'),
(2, 101, 'Mouse', 25, '2024-07-20'),
(3, 102, 'Keyboard', 80, '2024-08-10');

INSERT INTO orders_2025 VALUES
(1, 101, 'Monitor', 350, '2025-01-05'),
(2, 103, 'Webcam', 90, '2025-02-12'),
(3, 101, 'Laptop', 1200, '2025-03-20');  -- 与 2024 重复

1. 合并两个表(去重)

-- 查找所有年份的订单(去重)
SELECT user_id, product, amount FROM orders_2024
UNION
SELECT user_id, product, amount FROM orders_2025
ORDER BY amount DESC;

结果Laptop 只出现一次):

user_id | product  | amount
--------|----------|-------
101     | Laptop   | 1200
101     | Monitor  | 350
103     | Webcam   | 90
102     | Keyboard | 80
101     | Mouse    | 25

2. 使用 UNION ALL(保留重复)

SELECT user_id, product, amount FROM orders_2024
UNION ALL
SELECT user_id, product, amount FROM orders_2025
ORDER BY amount DESC;

结果Laptop 出现两次):

101 | Laptop   | 1200
101 | Laptop   | 1200
101 | Monitor  | 350
103 | Webcam   | 90
102 | Keyboard | 80
101 | Mouse    | 25

3. 不同列名对齐(使用别名)

SELECT user_id AS uid, product AS item, amount AS price FROM orders_2024
UNION ALL
SELECT customer_id AS uid, item_name AS item, total AS price FROM legacy_orders

4. 替代复杂 OR 条件

-- 查找 IT 或 HR 部门员工(避免 OR 影响索引)
SELECT name, department FROM employees WHERE department = 'IT'
UNION
SELECT name, department FROM employees WHERE department = 'HR';

WHERE department IN ('IT', 'HR') 更易利用索引


5. 合并统计结果

-- 2024 年总销售额
SELECT '2024' AS year, SUM(amount) AS total FROM orders_2024
UNION ALL
SELECT '2025' AS year, SUM(amount) AS total FROM orders_2025
ORDER BY year;

6. 分页 + UNION

-- 第 2 页,每页 3 条
(SELECT * FROM orders_2024 ORDER BY order_date DESC LIMIT 3 OFFSET 3)
UNION ALL
(SELECT * FROM orders_2025 ORDER BY order_date DESC LIMIT 3 OFFSET 3)
ORDER BY order_date DESC
LIMIT 3;

注意:ORDER BYLIMIT 需加括号作用于子查询


7. 性能优化

-- 为 UNION 字段建索引
CREATE INDEX idx_2024_user_amount ON orders_2024(user_id, amount);
CREATE INDEX idx_2025_user_amount ON orders_2025(user_id, amount);
  • UNION ALLUNION 快(无需排序去重)
  • 优先使用 UNION ALL 除非明确需要去重

常见错误

错误正确做法
列数不匹配确保每个 SELECT 列数相同
类型不兼容TEXT vs INTEGER 会报错
ORDER BY 放错位置必须在最后,或子查询内
-- 错误
SELECT id, name FROM users UNION SELECT email FROM profiles;

-- 正确
SELECT id, name FROM users UNION SELECT id, email FROM profiles;

快速参考

需求SQL
合并去重UNION
合并保留重复UNION ALL
排序最后加 ORDER BY
分页子查询加 LIMIT
统计汇总各表 SELECT 'label', SUM()

最佳实践

  1. 优先用 UNION ALL(性能高)
  2. 列数、顺序、类型必须一致
  3. 复杂排序/分页用子查询包裹
  4. 为连接字段建索引

需要我帮你写一个针对你分表的 UNION 查询吗?
请提供表名、公共字段和合并需求!

文章已创建 2305

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部