Допустим, что есть какая-то задача, которую вы не можете решить в один запрос. Например, допустим, что нужно выбрать из таблицы все записи, в которых в поле "vcName" указано имя Андрей, а в поле "vcSurName" указана фамилия Васильевич. При этом, если запись удовлетворяет и тому и другому условию, то она должна быть выведена в результате дважды. Как решить эту задачу? Если написать запрос:
SELECT vcFamil, vcName, vcSurName FROM tbPeoples WHERE vcName='Андрей' OR vcSurName='Васильевич'
То оба условия будут описаны верно, но в результате человек с именем и отчеством Андрей Васильевич попадет в результат только один раз, а нам надо два.
Проблема решается выполнением двух запросов. Сначала необходимо определить все записи с именем Андрей, а потом с отчеством Васильевич. Но это будет два набора результата. Как их объединить в один? Для этого между запросами нужно написать один из следующих операторов:
Для решения нашей задачи нужно использовать UNION ALL, чтобы ни одна строка не исчезла и если какая-то запись соответствует двум условиям, она должна попадать в результат дважды:
SELECT vcFamil, vcName, vcSurName FROM tbPeoples WHERE vcName='Андрей' UNION ALL SELECT vcFamil, vcName, vcSurName FROM tbPeoples WHERE vcSurName='Васильевич'
Как видите, это всего лишь два запроса, между которыми стоит ключевое слово UNION ALL. У объединения есть одно ограничение – сортировку надо указывать только во втором запросе. Если поставить оператор ORDER BY в первом запросе, то в результате вы получите ошибку. А если указать во втором, то сортироваться будет весь результат (обоих запросов) как одно целое.
Чтобы в результирующем наборе было видно, какая запись была получена первым запросом, а какая вторым, давайте добавим еще одну колонку к каждому из запросов, в которой будет отображаться текст с номером запроса:
SELECT vcFamil, vcName, vcSurName, 'Запрос 1' FROM tbPeoples WHERE vcName='Андрей' UNION ALL SELECT vcFamil, vcName, vcSurName, 'Запрос 2' FROM tbPeoples WHERE vcSurName='Васильевич'
Не все так красиво у оператора UNION. У него есть следующие ограничения в использовании:
Подобные запросы очень эффективны, когда нужно обращаться к разным базам данных. Например, один запрос выбирает данные из базы данных Database1, а другой из Database2.
Если одного поля в одном из запросов нет, то его можно заменить. Например, допустим, что во втором запросе происходит обращение к таблице, в которой нет поля фамилии. Да, у нас обращение идет к одной и той же таблице, но мы просто представим такую ситуацию. Как можно решить проблему? Вместо поля можно указать какой-либо текст, например:
SELECT vcFamil, vcName, vcSurName, 'Запрос 1' FROM tbPeoples WHERE vcName='Андрей' UNION ALL SELECT 'Не найдено', vcName, vcSurName, 'Запрос 2' FROM tbPeoples WHERE vcSurName='Васильевич' ORDER BY vcFamil
В данном примере, во втором запросе вместо поля фамилии указывается текст 'Не найдено'. Для числового поля, вместо не существующего поля, конечно же, нужно указать число.