SELECT *
FROM A
LEFT JOIN B ON A.seq = B.seq
WHERE (select max(B.data) where B.data is not null group by B.seq);
Это не может быть вашим реальным запросом.Это не действительный SQL.Вот что я получаю при тестировании:
ОШИБКА 1064 (42000): у вас ошибка в синтаксисе SQL;проверьте руководство, соответствующее вашей версии сервера MySQL, на предмет правильного синтаксиса, который можно использовать рядом со значением «где B.data не является пустой группой по B.seq)» в строке 4
Без сомнения, поскольку это не разрешено закономсинтаксис для использования предложения where
или любого следующего за ним предложения, если у вас нет предложения from
для определения ссылки на таблицу.
Тест, который я провел выше, был в MySQL 5.6,и я подтвердил, что он возвращает ту же ошибку при запуске запроса в MySQL Workbench.
Однако MySQL 8.0 поддерживает новый синтаксис.Вы можете использовать WHERE
и другие предложения без предложения FROM
.Я не осознавал этого раньше.
Я извиняюсь за снисходительность, обвиняя вас в том, что вы не проверяете ошибки.
Вот демонстрационная версия:
mysql> select version();
+-----------+
| version() |
+-----------+
| 8.0.17 |
+-----------+
1 row in set (0.00 sec)
mysql> select 42;
+----+
| 42 |
+----+
| 42 |
+----+
1 row in set (0.00 sec)
mysql> select 42 where true;
+----+
| 42 |
+----+
| 42 |
+----+
1 row in set (0.00 sec)
mysql> select 42 where false;
Empty set (0.00 sec)
MySQL всегда поддерживаетсявыбрать одну строку, указав набор фиксированных выражений в списке выбора.Теперь с новым синтаксисом вы можете сделать так, чтобы эта строка оставалась или отфильтровывалась в зависимости от того, верно ли условие WHERE
или нет.
В вашем запросе подзапрос оценивается для каждой строкивнешний запрос, поэтому столбцы B.data
и B.seq
в подзапросе имеют одно значение при каждом запуске подзапроса.Как будто вы сделали постоянное выражение.GROUP BY
не имеет значения, так как в любом случае есть только одно значение для B.seq
.
Гордон Линофф прав, что предложение WHERE
внешнего запроса будет либо ложным, если max(B.data)
равно 0, либоистина, если это не ноль.Если условие подзапроса WHERE
равно false, то подзапрос не вернет ни одной строки, что ведет себя так же, как если бы он вернул false.
mysql> SELECT * FROM A LEFT JOIN B ON A.seq = B.seq WHERE (select true where true);
+-----+------+------+
| seq | seq | data |
+-----+------+------+
| 1 | 1 | data |
+-----+------+------+
1 row in set (0.00 sec)
mysql> SELECT * FROM A LEFT JOIN B ON A.seq = B.seq WHERE (select true where false);
Empty set (0.00 sec)
Или, если max(b.data)
возвращает значение, которое интерпретируется какноль / ложь, это также заставляет подзапрос оценивать как ложный, поэтому внешний запрос не возвращает строк.
mysql> SELECT * FROM A LEFT JOIN B ON A.seq = B.seq WHERE (select 0 where true);
Empty set (0.00 sec)
mysql> SELECT * FROM A LEFT JOIN B ON A.seq = B.seq WHERE (select 'abc' where true);
Empty set, 1 warning (0.00 sec)
mysql> show warnings;
+---------+------+-----------------------------------------+
| Level | Code | Message |
+---------+------+-----------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: 'abc' |
+---------+------+-----------------------------------------+