【问题标题】:mysql dependent subquery stops working when using a constantmysql依赖子查询在使用常量时停止工作
【发布时间】: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


    【解决方案1】:

    这在本地 10.1.25-MariaDB 上对我来说是开箱即用的:

    试过this 5.6 fiddle,它成功了。

    试过this 5.7 fiddle 也成功了

    我查看了您的代码,但没有看到任何明显的此错误原因,您是否尝试过其他 5.7 实例以排除任何可能的本地原因?

    问候,

    詹姆斯

    【讨论】:

    • 是的,我已经在 3 个实例(2 个 Linux 服务器和 1 个我的本地 Windows 10)上复制了这个。我们使用多字节默认字符集,所以我认为这与它有关。如果您将“DEFAULT CHARSET=utf8mb4”添加到您的 db-fiddle 中每个创建表的末尾,您可以在那里重现它。
    • 这个错误似乎只发生在 5.7 中(5.6 db-fiddle 仍然适用于字符集更改)
    • 谢谢,我会根据该信息继续提交错误报告 - 目前无法访问 MySQL 5.7 机器,但很高兴尝试 Percona 5.7
    【解决方案2】:

    试试这个吧……给猫剥皮的方法总是不止一种。

    select a.id as 'aid',
           b.id as 'bib', 
           d.col3 as 'shouldBe7'
    from tableA a
         inner join tableC c on c.refA = a.id
         inner join tableB b on c.refB = b.id
    inner join ( select col3, refA, refB from tableD ) as d
        on d.refA=a.id and d.refB=b.id
    where a.id='123'
    group by a.id, b.id
    ;
    

    【讨论】:

      猜你喜欢
      • 2014-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-14
      • 2011-06-17
      • 2017-04-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多