暂无图片
mysql5.7 sql问题请教
我来答
分享
惜和
2020-12-05
mysql5.7 sql问题请教

image.png

用left join 查无数据。使用join查有数据
image.png

没想明白为什么。请各路大神帮忙想想原因。

我来答
添加附件
收藏
分享
问题补充
4条回答
默认
最新
文成

造了个示例,没有复现问题

CREATE TABLE t1(id INT);
CREATE TABLE t2(id INT);
CREATE TABLE t3(id INT);

INSERT INTO t1 VALUES(1),(2);
INSERT INTO t2 VALUES(1),(3);
INSERT INTO t3 VALUES(1),(4);

mysql> SELECT * FROM t1 
    -> LEFT JOIN(
    -> SELECT t2.id FROM t2 JOIN t3 ON t2.id=t3.id
    -> ) t  ON t1.id=t.id;
+------+------+
| id   | id   |
+------+------+
|    1 |    1 |
|    2 | NULL |
+------+------+
2 rows in set (0.00 sec)

mysql> EXPLAIN SELECT * FROM t1 
    -> LEFT JOIN(
    -> SELECT t2.id FROM t2 JOIN t3 ON t2.id=t3.id
    -> ) t  ON t1.id=t.id;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra                                              |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------------------------------------------+
|  1 | SIMPLE      | t1    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    2 |   100.00 | NULL                                               |
|  1 | SIMPLE      | t2    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    2 |   100.00 | Using where; Using join buffer (Block Nested Loop) |
|  1 | SIMPLE      | t3    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    2 |   100.00 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------------------------------------------+
3 rows in set, 1 warning (0.00 sec)
mysql> SELECT * FROM t1 
    -> JOIN(
    -> SELECT t2.id FROM t2 JOIN t3 ON t2.id=t3.id
    -> ) t  ON t1.id=t.id;
+------+------+
| id   | id   |
+------+------+
|    1 |    1 |
+------+------+
1 row in set (0.00 sec)

mysql> EXPLAIN SELECT * FROM t1 
    -> JOIN(
    -> SELECT t2.id FROM t2 JOIN t3 ON t2.id=t3.id
    -> ) t  ON t1.id=t.id;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra                                              |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------------------------------------------+
|  1 | SIMPLE      | t1    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    2 |   100.00 | NULL                                               |
|  1 | SIMPLE      | t2    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    2 |    50.00 | Using where; Using join buffer (Block Nested Loop) |
|  1 | SIMPLE      | t3    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    2 |    50.00 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------------------------------------------+
3 rows in set, 1 warning (0.00 sec)

复制

你可以提供一下测试数据,以及执行计划看看

暂无图片 评论
暂无图片 有用 0
打赏 0
惜和
上传附件:测试数据.sql
暂无图片 评论
暂无图片 有用 0
打赏 0
惜和

@文成
你这个和我写的不一样。
你这种我试过,没问题。
我把sql文件上传了。
我用的是mysql5.7.20,用mysql5.7.30也有问题。用mysql8就没问题了。应该是mysql的一个bug

暂无图片 评论
暂无图片 有用 0
打赏 0
文成

嗯,看起来是where子句中or的问题,可能他转换有问题
如果写成 union 则结果正常

SELECT
 *
FROM
 t_host h
LEFT JOIN (
 SELECT
  r.relation_id,
  tag_name
 FROM
  t_tag t
 JOIN t_tag_relation r ON t.id = r.tag_id
 AND r.type = 2
) tag ON h.id = tag.relation_id
WHERE  
 tag.tag_name IN ('ggg')
 UNION   SELECT
 *
FROM
 t_host h
LEFT JOIN (
 SELECT
  r.relation_id,
  tag_name
 FROM
  t_tag t
 JOIN t_tag_relation r ON t.id = r.tag_id
 AND r.type = 2
) tag ON h.id = tag.relation_id 
  WHERE h.host_name IN ('0000000')
 
复制
暂无图片 评论
暂无图片 有用 0
打赏 0
回答交流
Markdown


请输入正文
提交
相关推荐
mysql根据成绩排名次代码解读
回答 1
伪列理解难度是要稍微大些,建议用mysql8的窗口函数rownumber()over(orderbyfield)
mysql 可以指定用户默认的 通用表空间 吗?
回答 2
已采纳
建立一个表空间,如果想其他建表都用这个表空间,建表时候指定一下,否则不会用。
MySQL 用什么方法可以判断是什么程序在扫描磁盘?
回答 1
已采纳
yuminstalliotopiotop
mysql的错误日志怎么清理 ,可以直接清空吗?
回答 1
已采纳
可以。慢日志也可以。不过建议你切分报错。日后查问题好查啊。
mysql单表一般最大存多少数据?
回答 1
已采纳
innodb理论上64T。实际上很少有人做到这个。多大不是问题。就看你维护的了吗?我以前oracle单表100TB也没问题,但是有人mysql1T就不行了。不是数据库的问题,是人的问题。
mysql有没有类似oracle的tnsnames.ora文件,可以统一更改数据库地址
回答 1
已采纳
没有的
mysql 表union +group by 查询优化
回答 2
UNION改成UNIONALL?
MySQL中有以下SQL,使用了多个hint提示
回答 3
已采纳
选DUSEINDEX(empjob2)
mysql支持修改分区表的分区列的类型或者长度吗?
回答 2
可以修改的,但是在表中有数据的情况下,修改列的数据类型会容易造成数据混乱,数据长度在允许的范围内是可以修改的mysql>showcreatetableemployees\G1.rowTable:
mysql数据库备份怎么避开federated引擎?
回答 1
mysqlpump支持。就是要分开写。