在SQLite的实际开发中,我们经常会遇到需要同时获取两个表关联数据的情况,比如用户表和订单表通过用户ID关联,需要查询每个订单对应的用户信息,这时候就需要用到基于ID的关联查询。下面我们就详细介绍具体的实现方法。

基础表结构准备
首先我们创建两个测试表,用户表users和订单表orders,两个表通过user_id字段进行关联,orders表中的user_id对应users表的id字段。
-- 创建用户表
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL,
email TEXT NOT NULL
);
-- 创建订单表,user_id关联users表的id
CREATE TABLE IF NOT EXISTS orders (
id INTEGER PRIMARY KEY AUTOINCREMENT,
order_no TEXT NOT NULL,
amount REAL NOT NULL,
user_id INTEGER,
FOREIGN KEY (user_id) REFERENCES users(id)
);内连接查询(INNER JOIN)
内连接是最常用的关联方式,只会返回两个表中ID匹配到的记录,如果某个用户在orders表中没有订单,或者某个订单的user_id在users表中不存在,这类记录都不会被返回。
-- 查询所有有订单的用户及其订单信息
SELECT
u.id AS user_id,
u.username,
u.email,
o.order_no,
o.amount
FROM users u
INNER JOIN orders o ON u.id = o.user_id;上面的语句中,我们给users表起了别名u,orders表起了别名o,通过ON u.id = o.user_id指定关联条件,同时给users表的id字段起了别名user_id,避免和orders表的id字段混淆。
左连接查询(LEFT JOIN)
左连接会返回左表(这里是users表)的所有记录,即使右表(orders表)中没有匹配的记录,右表的字段会显示为NULL。如果需要查询所有用户,包括没有下单的用户,就可以使用左连接。
-- 查询所有用户及其订单信息,没有订单的用户订单字段为NULL
SELECT
u.id AS user_id,
u.username,
u.email,
o.order_no,
o.amount
FROM users u
LEFT JOIN orders o ON u.id = o.user_id;关联查询注意事项
- 关联条件必须明确指定,避免产生笛卡尔积,也就是两个表的所有记录两两组合,会造成查询结果数量异常膨胀。
- 如果两个表有同名的字段,一定要给字段起别名,否则查询结果中会出现字段名重复的问题,无法正确区分字段来源。
- SQLite中不支持RIGHT JOIN和FULL OUTER JOIN,如果需要实现右连接的效果,可以交换两个表的位置使用左连接,全外连接可以通过左连接加右连接去重的方式实现。
- 关联查询时可以添加WHERE条件过滤结果,比如只查询订单金额大于100的记录,只需要在关联语句后添加
WHERE o.amount > 100即可。
结果示例说明
假设我们的users表有以下数据:
| id | username | |
|---|---|---|
| 1 | 张三 | zhangsan@ipipp.com |
| 2 | 李四 | lisi@ipipp.com |
orders表有以下数据:
| id | order_no | amount | user_id |
|---|---|---|---|
| 1 | ORD202401 | 199.5 | 1 |
| 2 | ORD202402 | 89.0 | 1 |
使用内连接查询后,只会返回张三的两条订单记录,李四因为没有订单不会被查询出来;使用左连接查询的话,会返回张三的两条订单记录,以及李四的记录,李四对应的订单字段都为NULL。