暂无图片
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


请输入正文
提交
相关推荐
关于percona mysql下载的问题
回答 2
https://www.percona.com/downloads/PerconaServerLATEST/
innodbcluster在两个节点同时故障时如何自动恢复?
回答 1
MGR3节点的单主模式,如果有两个节点主机宕机,临时对外提供服务的方法
请问,数据虚拟化,这个概念现在还有人提吗?有何发展?
回答 1
看了一下百度百科:了解是一种概念性的说法。数据虚拟化(datavirtualization)这个词可能有点令人困惑,因为有些厂商互换地使用数据虚拟化和数据联合(datafederation)。但是两者
mysql造成数据不一致的原因
回答 3
已采纳
造成主从不一致的原因(1)主库binlog格式为Statement,同步到从库执行后可能造成主从不一致。(2)主库执行更改前有执行setsqllogbin0,会使主库不记录binlog,从库也无法变更
MySQL出现“Lost connection to MySQL server during query”
回答 3
已采纳
加大maxallowedpacket参数,重启测试如果你使用的是工具,可能还有工具的设置也有问题,比如workbench有超时时间30秒
MySQL数据库在什么情况下收集表统计信息?
回答 1
已采纳
数据库表的统计信息可以通过MySQL自动收集,也可以手动进行收集。MySQL会在以下情况下自动执行统计信息的收集:1)第一次打开表的时候。2)表修改的行超过1/6或者20亿条及以上时。3)当有新记录插
binlog 记录的时间不是顺序的。一般在什么情况下发生?
回答 1
你观察到的是MySQLbinlog文件记录时间戳不连续的现象。这通常是由于MySQL的并发操作、系统负载、网络延迟等因素导致的。尽管binlog文件记录了数据库中所有更改的历史,但它们并不是按照绝对时
mysql 使用乐观锁更新和悲观锁更新有什么区别呢? update 时不是都会上锁嘛?
回答 1
已采纳
悲观锁是一上来就假设有人在操作,先锁定。乐观锁是一上来不锁,认为没人在操作,只要在提交时候才去检查有没有。
如果修改了用户权限, 必须要MySQL服务重启 再用这个用户登录 ,权限才能生效吗?
回答 1
已采纳
不需要重启mysql服务,赋予权限之后执行flushprivileges;刷新一下权限即可。
default-character-set 在8.0中默认是utf8mb4,在5.7中对应的功能相同的参数是什么?
回答 1
[client]port7306defaultcharactersetutf8mb4 客户端默认字符集[mysqld]port7306charactersetserverutf8mb4&nb