mysql---多表查询

很多应用场景下,数据查询会涉及多张表,即多表查询。这些表之间存在连结关系。
多表连结分为:内连结,外连结, 交叉连结。
针对内外连结对应不同的连结方法

  • 内连结:(inner)join
  • 外连结:left(outer) join, right(outer) join, union
  • 交叉连结:cross join

其中,
1. join和inner join是等价的
2. left join和left outer join是等价的,right join和right outer join是等价的;
3. union本来不属于连结方法,用来组合其他连结方法实现新的连结方法。

下面通过实例对这些连结方法进行描述,首先建立两张表

表a:
+------+---------+
| c_id | country |
+------+---------+
|    1 | CHINA   |
|    2 | UK      |
|    3 | USA     |
+------+---------+
表b:
+------+--------+
| n_id | name   |
+------+--------+
|    2 | Mike   |
|    3 | Hanson |
|    4 | Jack   |
+------+--------+

1. 内连结


使用inner join或者join

SELECT a.*, b.*
FROM a JOIN b
ON a.c_id = b.n_id;

或者

SELECT a.*, b.*
FROM a INNER JOIN b
ON a.c_id = b.n_id;

结果:
+------+---------+------+--------+
| c_id | country | n_id | name   |
+------+---------+------+--------+
|    2 | UK      |    2 | Mike   |
|    3 | USA     |    3 | Hanson |
+------+---------+------+--------+

求两个表的交集

2. 外连结

2.1 左外连结1


使用left outer join或者left join

SELECT a.*, b.*
FROM a LEFT JOIN b
ON a.c_id = b.n_id;

或者:
SELECT a.*, b.*
FROM a LEFT OUTER JOIN b
ON a.c_id = b.n_id;

结果:
+------+---------+------+--------+
| c_id | country | n_id | name   |
+------+---------+------+--------+
|    2 | UK      |    2 | Mike   |
|    3 | USA     |    3 | Hanson |
|    1 | CHINA   | NULL | NULL   |
+------+---------+------+--------+

以a表为基准,b表中没有的直接补NULL
这样得到的结果是,a的所有数据和满足一定条件的b的部分数据

2.2 左外连结2

SELECT a.*, b.*
FROM a LEFT JOIN b
ON a.c_id = b.n_id
WHERE b.n_id IS NULL;

+------+---------+------+------+
| c_id | country | n_id | name |
+------+---------+------+------+
|    1 | CHINA   | NULL | NULL |
+------+---------+------+------+

2.3 右外连结1

SELECT a.*, b.* 
FROM a RIGHT JOIN b
ON a.c_id = b.n_id
WHERE a.c_id IS NULL; 

+------+---------+------+------+
| c_id | country | n_id | name |
+------+---------+------+------+
| NULL | NULL    |    4 | Jack |
+------+---------+------+------+

2.4 右外连结2

SELECT a.*, b.* 
FROM a RIGHT JOIN b
ON a.c_id = b.n_id;

+------+---------+------+--------+
| c_id | country | n_id | name   |
+------+---------+------+--------+
|    2 | UK      |    2 | Mike   |
|    3 | USA     |    3 | Hanson |
| NULL | NULL    |    4 | Jack   |
+------+---------+------+--------+

2.5 全连结1


mysql不支持这种连结,但可以使用left join union right join来实现

SELECT a.*, b.*
FROM a LEFT JOIN b
ON a.c_id = b.n_id

UNION

SELECT a.*, b.* 
FROM a RIGHT JOIN b
ON a.c_id = b.n_id;

+------+---------+------+--------+
| c_id | country | n_id | name   |
+------+---------+------+--------+
|    2 | UK      |    2 | Mike   |
|    3 | USA     |    3 | Hanson |
|    1 | CHINA   | NULL | NULL   |
| NULL | NULL    |    4 | Jack   |
+------+---------+------+--------+

2.6 全连结2

SELECT a.*, b.*
FROM a LEFT JOIN b
ON a.c_id = b.n_id
WHERE b.n_id IS NULL

UNION

SELECT a.*, b.* 
FROM a RIGHT JOIN b
ON a.c_id = b.n_id
WHERE a.c_id IS NULL;

+------+---------+------+------+
| c_id | country | n_id | name |
+------+---------+------+------+
|    1 | CHINA   | NULL | NULL |
| NULL | NULL    |    4 | Jack |
+------+---------+------+------+

3. 交叉连结

得到两个表的笛卡尔积

SELECT a.* 
FROM a CROSS JOIN b;

+------+---------+
| c_id | country |
+------+---------+
|    1 | CHINA   |
|    2 | UK      |
|    3 | USA     |
|    1 | CHINA   |
|    2 | UK      |
|    3 | USA     |
|    1 | CHINA   |
|    2 | UK      |
|    3 | USA     |
+------+---------+
要实现订单详情,我们可以在订单表中添加一些额外的字段来保存订单的详细信息,例如订单状态、收货地址、支付方式等等。假设我们需要保存以下信息: - 订单号(order_no):表示订单的唯一标识,可以通过自增长主键或者使用 UUID 算法等方式生成。 - 订单状态(status):表示订单的当前状态,例如已下单、已付款、已发货、已完成等等。 - 提交订单时间(order_time):表示用户提交订单的时间。 - 付款时间(payment_time):表示用户完成支付的时间。 - 发货时间(delivery_time):表示商城发货的时间。 - 收货时间(receive_time):表示用户收货的时间。 - 评价时间(comment_time):表示用户对购物体验的评价时间。 - 收货人姓名(receiver_name):表示收货人的姓名。 - 邮政编码(postal_code):表示收货地址的邮政编码。 - 联系电话(contact_phone):表示收货人的联系电话。 - 收货地址(delivery_address):表示收货人的详细地址。 我们可以使用以下 SQL 语句向订单表中添加这些字段: ``` ALTER TABLE orders ADD COLUMN order_no VARCHAR(32) NOT NULL UNIQUE; ALTER TABLE orders ADD COLUMN status VARCHAR(255) NOT NULL DEFAULT '已下单'; ALTER TABLE orders ADD COLUMN order_time DATETIME NOT NULL; ALTER TABLE orders ADD COLUMN payment_time DATETIME; ALTER TABLE orders ADD COLUMN delivery_time DATETIME; ALTER TABLE orders ADD COLUMN receive_time DATETIME; ALTER TABLE orders ADD COLUMN comment_time DATETIME; ALTER TABLE orders ADD COLUMN receiver_name VARCHAR(255) NOT NULL; ALTER TABLE orders ADD COLUMN postal_code VARCHAR(6) NOT NULL; ALTER TABLE orders ADD COLUMN contact_phone VARCHAR(11) NOT NULL; ALTER TABLE orders ADD COLUMN delivery_address VARCHAR(255) NOT NULL; ``` 接下来,当用户提交订单时,我们可以生成一个唯一的订单号,并向订单表中插入一条新的订单记录: ``` INSERT INTO orders (order_no, status, order_time, receiver_name, postal_code, contact_phone, delivery_address) VALUES ('1101000301', '等待收货', '2018-12-2 20:32:17', '八戒', '100190', '1380***1234', '北京市房山区高老庄3排6号'); ``` 当用户完成支付时,我们可以更新订单表中的状态和支付时间: ``` UPDATE orders SET status = '已付款', payment_time = '2018-12-2 20:35:03' WHERE order_no = '1101000301'; ``` 当商城发货时,我们可以更新订单表中的状态和发货时间: ``` UPDATE orders SET status = '商城发货', delivery_time = '2018-12-3 08:13:34' WHERE order_no = '1101000301'; ``` 当用户收到货物时,我们可以更新订单表中的状态和收货时间: ``` UPDATE orders SET status = '用户收货', receive_time = NOW() WHERE order_no = '1101000301'; ``` 最后,当用户需要查看订单详情时,我们可以使用以下 SQL 查询语句: ``` SELECT * FROM orders WHERE order_no = '1101000301'; ``` 其中,'1101000301' 是订单的唯一标识。这条 SQL 语句将返回订单表中 order_no 为 '1101000301' 的订单记录,包括订单的所有详细信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值