@AShvejnov

MySQL и парадокс c LEFT JOIN ON(...) — где логика?

Столкнулся в работе с интересным явлением. База MySQL 5.7.26 (всё в UTF-8 и только).

Есть две таблицы, предположим. В обеих таблицах есть поля с уникальными значениями, являющимися по факту артикулами товаров. При этом в первой таблице это поле числовое, т.к. в ней хранятся только товары с целочисленными артикулами. А во второй таблице уже это поле VARCHAR(30), так как там лежит информация по артикулам, но в том числе там уже встречаются и артикулы смешанного вида, поэтому VARCHAR.

Структура table1:

5de7906707128251004091.png

Содержимое table1:

5de7909048b76273498501.png

Структура table2:

5de790b2811c3407465984.png

Содержимое table2:

5de790c01d474960695238.png

И вот в чём парадокс. Возникает он, когда делаем простейший запрос с LEFT JOIN, соединяя таблицы по сквозному полю с ID товара.

Если сделать вот такой запрос:

SELECT t1.t1_id, t2.* 
FROM table1 t1 
LEFT JOIN table2 t2
ON(t1.t1_id = t2.t2_id)


То получаем вот такой неожиданный/нежелательный результат:

5de7918f3bb09998458924.png

...а если в условии ON(...) тупо меняем оператор = на LIKE:

SELECT t1.t1_id, t2.* 
FROM table1 t1 
LEFT JOIN table2 t2
ON(t1.t1_id LIKE t2.t2_id)


...то получаем другой результат, желаемый (только точные соответствия 1-к-1):

5de79266c5601897143559.png

Вопрос: почему так? О__о

Я бы ещё мог ожидать обратного результата, если бы по LIKE цеплялись бы не только 1:1 соответствия, но ещё и какие-то похожие с суффиксами. Но тут же получается наоборот - вроде как требуем точного соответствия (=), а получаем в том числе и неточные. А по LIKE при этом наоборот получаем только 1:1 точные...

P.S. Если в обеих таблицах поле с ID сделать VARCHAR, то проблема уходит сама собой. Но это не отменяет вопроса, почему такой парадокс происходит, когда в одной таблице INT, а в другой VARCHAR.
  • Вопрос задан
  • 88 просмотров
Решения вопроса 1
Melkij
@Melkij
PostgreSQL DBA
Никакого парадокса, задокументированное поведение. Скопирую недавний ответ отсюда:
Потому что вообще не надо сравнивать строки и числа. Если поле строковое - сравнивайте только со строкой. Хоть при этом происходит и вполне задокументированное поведение.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы