【发布时间】:2018-03-10 14:23:29
【问题描述】:
使用 MySQL 5.7.17-log 我们有许多报告查询在选择语句中使用依赖子查询,当应该有一个值时返回 null。我知道这种风格可以重构为左连接,但我想了解我们遇到此问题的原因,并可能向 MySQL 提交错误。这是重现此问题的最简单方法:
CREATE TABLE tableA (
id varchar(36) NOT NULL,
col2 int(10) unsigned zerofill NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
;
CREATE TABLE tableB (
id varchar(36) NOT NULL,
col2 int(10) unsigned zerofill NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE tableC (
refA varchar(36) NOT NULL,
refB varchar(36) NOT NULL,
PRIMARY KEY (refA, refB),
CONSTRAINT fkCA FOREIGN KEY (refA) REFERENCES tableA (id),
CONSTRAINT fkCB FOREIGN KEY (refB) REFERENCES tableB (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE tableD (
refA varchar(36) NOT NULL,
refB varchar(36) NOT NULL,
col3 int(10) unsigned zerofill NOT NULL,
PRIMARY KEY (refA, refB),
CONSTRAINT fkDA FOREIGN KEY (refA) REFERENCES tableA (id),
CONSTRAINT fkDB FOREIGN KEY (refB) REFERENCES tableB (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
insert into tableA values ('123',5)
;
insert into tableB values ('234',6)
;
insert into tableC values ('123','234')
;
insert into tableD values ('123','234',7)
;
select a.id as 'aid',
b.id as 'bib',
( select d.col3 from tableD d where d.refA=a.id and d.refB=b.id ) as 'shouldBe7'
from tableA a
inner join tableC c on c.refA = a.id
inner join tableB b on c.refB = b.id
where a.id='123'
group by a.id, b.id
;
select 语句产生 ['123','234',null],尽管我期望 ['123','234',7]。如果您删除语句中的 where 子句(其中 a.id='123'),您将得到预期的结果 - ['123','234',7]。
我对整个 select 语句进行了解释,发现“ref”使用了一个我做了 SHOW WARNINGS 的函数,并且依赖子查询将 id 与空字符串进行比较。
(/* select#2 */ select dev.d.col3 from dev.tableD d where ((dev.d.refA = '') 和(dev.d.refB = dev.b.id))) 作为shouldBe7
似乎是 5.7 的错误...我已提交 http://bugs.mysql.com/87915 。 db-fiddle 工具很有帮助 - 谢谢 James!
【问题讨论】:
标签: mysql