简体   繁体   中英

mysql dependent subquery stops working when using a constant

Using MySQL 5.7.17-log We have a number of report queries using a dependent subquery in the select statement that is returning null when there should be a value. I know this style can be refactored into a left join but I wanted to understand the reason we are having this problem and possibly file a bug with MySQL. Here is the simplest way to reproduce this:

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
;

The select statement produces ['123','234',null] although I would expect ['123','234',7]. If you remove the where clause in the statement (where a.id='123'), the expected result - ['123','234',7] is what you get. I did an explain on the whole select statement and saw that the "ref" uses a func which I did a SHOW WARNINGS and the dependent subquery is comparing the id against an empty string. (/* select#2 */ select dev . d . col3 from dev . tableD d where (( dev . d . refA = '') and ( dev . d . refB = dev . b . id ))) AS shouldBe7

Seems like a 5.7 bug...I've filed http://bugs.mysql.com/87915 . the db-fiddle tool was helpful - thanks James!

This ran out of the box for me on 10.1.25-MariaDB locally:

Tried this 5.6 fiddle and it worked.

Tried this 5.7 fiddle and it also worked

I had a look at your code but couldn't see any obvious causes of this error, have you tried on other 5.7 instances to rule out any possible local causes?

Regards,

James

Try this instead...there's always more than one way to skin a cat.

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
;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM