MySQL 如何在MySQL数据库中使用另一张表中的ID获取用户名?
在实际应用中,经常会遇到需要使用另一张表中的一个或者多个ID来获取对应的用户名的需求。这时候,我们可以使用MySQL中的JOIN语句来实现。
阅读更多:MySQL 教程
1. 创建测试数据
为了方便演示,我们先创建两张表,一张是users表,包括用户的ID、用户名和密码;另外一张是orders表,包括订单的ID、订单编号和用户ID字段。
我们使用以下SQL语句创建两张表:
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`username` varchar(50) NOT NULL COMMENT '用户名',
`password` varchar(50) NOT NULL COMMENT '密码',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
CREATE TABLE IF NOT EXISTS `orders` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`order_no` varchar(50) NOT NULL COMMENT '订单编号',
`user_id` int(11) NOT NULL COMMENT '用户ID',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表';
然后,我们向users表中插入一些测试数据:
INSERT INTO `users` (`id`, `username`, `password`) VALUES
(1, 'bob', '123456'),
(2, 'alice', 'qwerty'),
(3, 'tom', '112233');
再向orders表中插入一些测试数据:
INSERT INTO `orders` (`id`, `order_no`, `user_id`) VALUES
(1, '20190101001', 1),
(2, '20190101002', 2),
(3, '20190101003', 1),
(4, '20190101004', 3),
(5, '20190101005', 2);
2. 使用JOIN语句获取用户名
有了测试数据之后,我们就可以使用JOIN语句来获取用户名了。下面是一个简单的例子:
SELECT `o`.`id`, `o`.`order_no`, `u`.`username`
FROM `orders` AS `o`
LEFT JOIN `users` AS `u` ON `o`.`user_id` = `u`.`id`;
这个查询语句中,我们使用了JOIN语句将orders表和users表连接在一起。这里我们使用了LEFT JOIN,即左连接,表示如果orders表中的记录没有对应的users表中的记录,则仍然返回orders表中的记录,但是users表中的相关字段为NULL。
在这个查询语句中,我们使用了AS语句为表orders和表users分别指定了别名o和u,这样可以方便后面的语句中引用各自的字段。
查询结果如下:
+----+-------------+----------+
| id | order_no | username |
+----+-------------+----------+
| 1 | 20190101001 | bob |
| 2 | 20190101002 | alice |
| 3 | 20190101003 | bob |
| 4 | 20190101004 | tom |
| 5 | 20190101005 | alice |
+----+-------------+----------+
从这个结果中,我们可以看到每个订单的ID、订单编号和用户名。可以看到,使用JOIN语句可以很方便地把来自多个表的信息集成到一个查询结果中。
3. 使用子查询获取用户名
除了JOIN语句,我们还可以使用子查询来完成这个任务。下面是一个使用子查询的例子:
SELECT `id`, `order_no`,
(SELECT `username` FROM `users` WHERE `id`=`user_id`) AS `username`
FROM `orders`;
在这个查询语句中,我们使用了一个子查询,查询出了每个订单的用户ID,并在外层查询中使用了一个SELECT语句来查询出对应的用户名。需要注意的是,子查询语句的执行是在外层查询中执行的,因此会导致比较差的性能,特别是在数据量比较大的情况下。
查询结果如下:
+----+-------------+----------+
| id | order_no | username |
+----+-------------+----------+
| 1 | 20190101001 | bob |
| 2 | 20190101002 | alice |
| 3 | 20190101003 | bob |
| 4 | 20190101004 | tom |
| 5 | 20190101005 | alice |
+----+-------------+----------+
从这个结果中,我们可以看到每个订单的ID、订单编号和用户名。可以看到,使用子查询的方式虽然也能够获得正确的结果,但是性能会受到影响,因此不建议在实际应用中使用。
4. 性能比较
为了进一步比较JOIN语句和子查询的性能差异,我们使用EXPLAIN语句观察一下它们的执行计划。下面是使用JOIN语句的查询语句的执行计划:
EXPLAIN SELECT `o`.`id`, `o`.`order_no`, `u`.`username`
FROM `orders` AS `o`
LEFT JOIN `users` AS `u` ON `o`.`user_id` = `u`.`id`;
执行结果如下:
+----+-------------+-------+------------+------+---------------+---------+---------+----------------+------+----------+--------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+---------+---------+----------------+------+----------+--------------------------+
| 1 | SIMPLE | o | NULL | ALL | NULL | NULL | NULL | NULL | 5 | 100.00 | NULL |
| 1 | SIMPLE | u | NULL | eq_ref | PRIMARY | PRIMARY | 4 | test.o.user_id | 1 | 100.00 | NULL |
+----+-------------+-------+------------+------+---------------+---------+---------+----------------+------+----------+--------------------------+
从这个执行计划中,我们可以看到使用了LEFT JOIN,orders表中有5行记录,users表中有1行记录,查询结果会返回5行记录。
下面是使用子查询的查询语句的执行计划:
EXPLAIN SELECT `id`, `order_no`,
(SELECT `username` FROM `users` WHERE `id`=`user_id`) AS `username`
FROM `orders`;
执行结果如下:
+----+--------------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+--------------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| 1 | PRIMARY | orders| NULL | ALL | NULL | NULL | NULL | NULL | 5 | 100.00 | NULL |
| 2 | DEPENDENT SUBQUERY | users | NULL | ALL | PRIMARY | NULL | NULL | NULL | 3 | 100.00 | Using where |
+----+--------------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
从这个执行计划中,我们可以看到使用了子查询,查询orders表中有5行记录,又执行了一个子查询查询users表中的记录,users表中有3行记录。同时可以看到,这个查询的执行计划中使用了Using where,这说明在子查询中使用了WHERE条件来进行过滤。
从执行计划中可以看到,使用JOIN语句的性能比使用子查询要好,而且JOIN语句可以同时查询多张表,使得查询更加灵活。因此,在实际应用中,我们一般会优先考虑使用JOIN语句来完成这个任务。
结论
在MySQL数据库中,使用另一张表中的ID获取用户名,可以使用JOIN语句和子查询两种方式来实现。其中,JOIN语句的性能优于子查询,因此在实际应用中应该优先使用JOIN语句。同时,JOIN语句也更加灵活,可以方便地同时查询多张表的信息。在使用JOIN语句时,需要注意表的别名的使用,以便方便后续的查询和引用表的字段。