Обязательно ли совпадать колонкам и типам данных при UNION в SQL
Что проверяют
Понимаете ли вы, что UNION это операция над множествами, а не склейка двух запросов подряд. Вопрос обычно идёт в блоке про SQL на позиции, где код ходит в базу, и из него вырастает разговор про производительность.
Как отвечать
Количество колонок обязано совпадать, это жёсткое требование: разное число колонок в ветках даёт ошибку сразу. Сопоставление идёт по позиции, а не по имени: первая колонка первого запроса объединяется с первой колонкой второго, как бы они ни назывались. Имена в результате берутся из первой ветки.
С типами мягче: они должны приводиться к общему типу. Правила приведения зависят от СУБД, и это стоит сказать вслух. Одна база приведёт число к строке молча, другая откажется выполнять запрос, третья приведёт строку к числу и упадёт уже на данных, где в колонке лежит текст. Универсальная практика: приводить явно через cast, а не полагаться на неявное приведение.
Что стоит добавить самому:
UNIONубирает дубликаты по всем колонкам сразу,UNION ALLне убирает и потому дешевле: нет ни сортировки, ни хеширования;- при дедупликации
NULLсчитаются одинаковыми, хотя в обычном сравненииNULL = NULLне даёт истину; ORDER BYотносится ко всему объединению, пишется один раз в конце и опирается на имена из первой ветки или на номера колонок;- порядок строк без
ORDER BYне определён, даже если кажется, что ветки идут подряд.
В коде на C# это всплывает через ORM: Union транслируется в UNION, а Concat в UNION ALL, и первый вариант тихо добавляет дедупликацию на большом наборе.
Где спотыкаются
Думают, что колонки сопоставляются по именам. Запрос отрабатывает без ошибки, раз типы совместимы, а в отчёте город оказывается в колонке с именем.
Второе: ставят UNION по привычке. На больших выборках это лишний проход ради дедупликации, а иногда и потеря честных дубликатов, которые должны были попасть в результат.
Третье: заявляют, что несовместимые типы всегда дают ошибку. Это зависит от диалекта, и ответ «зависит от базы, поэтому типы привожу явно» звучит сильнее любого категоричного правила.