Bug #103150 | scalar expression returns empty result inside a CTE | ||
---|---|---|---|
Submitted: | 30 Mar 2021 9:11 | Modified: | 31 Mar 2021 8:42 |
Reporter: | Yushan ZHANG | Email Updates: | |
Status: | Not a Bug | Impact on me: | |
Category: | MySQL Server: Optimizer | Severity: | S3 (Non-critical) |
Version: | 8.0.23 | OS: | Any |
Assigned to: | CPU Architecture: | Any | |
Tags: | cte, scalar |
[30 Mar 2021 9:11]
Yushan ZHANG
[30 Mar 2021 11:59]
MySQL Verification Team
Hello Yushan ZHANG, Thank you for the report and test case. regards, Umesh
[31 Mar 2021 6:22]
Steinar Gunderson
Hi, A CTE is a _table_ expression. It returns zero or more rows; in your case, no rows exists, so it returns nothing. Thus, there is no bug here: mysql> select salary from employee order by salary desc limit 1,1; Empty set (0,00 sec) What you want is something like: mysql> select (select salary from employee order by salary desc limit 1 offset 1) as second_highest_salary; +-----------------------+ | second_highest_salary | +-----------------------+ | NULL | +-----------------------+ 1 row in set (0,00 sec) mysql> insert into employee values (1, 2000); Query OK, 1 row affected (0,00 sec) mysql> select (select salary from employee order by salary desc limit 1 offset 1) as second_highest_salary; +-----------------------+ | second_highest_salary | +-----------------------+ | 1000 | +-----------------------+ 1 row in set (0,00 sec) You can also solve this in many other ways, such as a left join against a derived table with window functions.
[31 Mar 2021 8:40]
Yushan ZHANG
Thanks for the explanation. But I don't understand why CTE's behavior is different in the following queries: If they should return an empty result for my test table, then both of the following should be empty. However, the first one returns 0, and the second returns 1. -- wrong with mid as ( select salary from employee order by salary desc limit 1,1 ) select (select count(*)=0 from mid)=1 from mid; -- correct with mid as ( select salary from employee order by salary desc limit 1,1 ) select count(*)=0 from mid;
[31 Mar 2021 8:42]
Yushan ZHANG
Sorry for atypo, the first has an empty result, and the second returns 1.
[31 Mar 2021 9:06]
Steinar Gunderson
The second query has an implicit aggregation due to the COUNT(*) in the outer query. SELECT COUNT(*) FROM t1 will yield exactly one row, even if t1 has no rows.