Будет ли работать SELECT * FROM table1 INNER JOIN table2 без условий
Что проверяют
Понимаете ли вы, что такое декартово произведение, и знаете ли, что поведение зависит от СУБД. Следом часто спрашивают, как получить такое произведение явно и где оно возникает в запросах из JPA.
Как отвечать
Короткий ответ: по стандарту SQL нет. INNER JOIN требует условия соединения через ON, USING или NATURAL, и большинство баз ответят ошибкой:
- PostgreSQL, Oracle, SQL Server: синтаксическая ошибка, запрос не выполнится;
- MySQL и MariaDB: запрос выполнится. Здесь
JOIN,INNER JOINиCROSS JOINсинтаксически равнозначны, безONполучится декартово произведение. При этомLEFT JOINбез условия и в MySQL ошибка; - SQLite: тоже вернёт декартово произведение.
Декартово произведение это каждая строка первой таблицы в паре с каждой строкой второй: при m и n строках результат m * n. Две таблицы по сто тысяч строк дают десять миллиардов строк, и такой запрос способен положить и базу, и приложение, которое пытается вычитать результат в память.
Если произведение действительно нужно, пишите CROSS JOIN: читатель сразу видит, что это намеренно. Реальные случаи: сетка «все даты на все товары» для отчёта с нулями, генерация тестовых комбинаций.
Для Java-разработчика стоит связать это с JPA. В JPQL FROM Order o, Customer c без WHERE тоже даёт произведение, а при соединении по связи (JOIN o.customer c) условие Hibernate подставляет сам по маппингу. Родственная ловушка: JOIN FETCH двух коллекций сразу размножает строки, а для двух List Hibernate и вовсе бросает MultipleBagFetchException.
Где спотыкаются
Отвечают «вернёт пустой результат» или «вернёт совпадающие строки». Без условия совпадать нечему: будет либо ошибка, либо все комбинации.
Выдают поведение одной базы за универсальное. Уточните, о какой СУБД речь, и назовите разницу: это и есть сильная часть ответа.
Забывают про старый синтаксис через запятую. FROM a, b без WHERE корректен во всех базах и молча возвращает то же произведение.