Комбинированные запросы

advertisement
Урок 14
Êîìáèíèðîâàííûå
çàïðîñû
 ýòîì óðîêå âû óçíàåòå, êàê èñïîëüçîâàòü îïåðàòîð
UNION äëÿ êîìáèíèðîâàíèÿ ìíîãèõ îïåðàòîðîâ SELECT ñ
öåëüþ ïîëó÷åíèÿ îäíîãî íàáîðà ðåçóëüòàòîâ.
×òî òàêîå êîìáèíèðîâàííûå
çàïðîñû
 áîëüøèíñòâå SQL-çàïðîñîâ èñïîëüçóåòñÿ îäèí îïåðàòîð, ïîñðåäñòâîì êîòîðîãî âîçâðàùàþòñÿ äàííûå èç îäíîé
èëè íåñêîëüêèõ òàáëèö. SQL ïîçâîëÿåò òàêæå âûïîëíÿòü
ìíîæåñòâåííûå çàïðîñû (çà ñ÷åò ìíîãîêðàòíîãî èñïîëüçîâàíèÿ îïåðàòîðà SELECT) è âîçâðàùàòü ðåçóëüòàòû â âèäå
îäíîãî íàáîðà ðåçóëüòàòîâ çàïðîñà. Ýòè êîìáèíèðîâàííûå
çàïðîñû îáû÷íî íàçûâàþò ñîåäèíåíèÿìè èëè ñëîæíûìè çàïðîñàìè.
Ìîæíî íàçâàòü äâà îñíîâíûõ ñöåíàðèÿ, äëÿ âûïîëíåíèÿ
êîòîðûõ âàì ïîíàäîáÿòñÿ ñëîæíûå çàïðîñû:
„ äëÿ âîçâðàùåíèÿ îäèíàêîâûì îáðàçîì ñòðóêòóðèðîâàííûõ äàííûõ èç ðàçëè÷íûõ òàáëèö ïîñðåäñòâîì
îäíîãî çàïðîñà;
„ äëÿ âûïîëíåíèÿ ìíîãîêðàòíûõ çàïðîñîâ ê îäíîé òàáëèöå è âîçâðàùåíèÿ äàííûõ â âèäå ðåçóëüòàòà îäíîãî
çàïðîñà.
146
Урок 14
Комбинированные запросы и многократные условия WHERE
Результат комбинирования двух запросов к одной и
той же таблице в основном аналогичен результату,
полученному при выполнении одного запроса с несколькими требованиями в предложении WHERE. Иначе говоря, как будет показано в следующем разделе,
любой оператор SELECT с многократно используемым условием WHERE можно также рассматривать как
сложный запрос.
Ñîçäàíèå êîìáèíèðîâàííûõ
çàïðîñîâ
Çàïðîñû â ÿçûêå SQL êîìáèíèðóþòñÿ ñ ïîìîùüþ îïåðàòîðà UNION. Îïåðàòîð UNION ïîçâîëÿåò ìíîãîêðàòíî óêàçûâàòü îïåðàòîð SELECT, è ïî çàâåðøåíèè èõ ðàáîòû ìîæåò
áûòü âûâåäåí îäèí íàáîð ðåçóëüòàòîâ.
Èñïîëüçîâàíèå îïåðàòîðà UNION
Èñïîëüçîâàòü îïåðàòîð UNION äîâîëüíî ïðîñòî. Âñå, ÷òî
âû äîëæíû ñäåëàòü, — ýòî óêàçàòü êàæäûé íåîáõîäèìûé
âàì îïåðàòîð SELECT è ðàçìåñòèòü êëþ÷åâîå ñëîâî UNION
ìåæäó íèìè.
Ðàññìîòðèì ïðèìåð. Äîïóñòèì, âàì íåîáõîäèì îò÷åò, ñîäåðæàùèé ñâåäåíèÿ îáî âñåõ êëèåíòàõ èç øòàòîâ Èëëèíîéñ,
Èíäèàíà è Ìè÷èãàí. Âû òàêæå õîòèòå âêëþ÷èòü â íåãî äàííûå î êëèåíòå Fun4All íåçàâèñèìî îò øòàòà. Êîíå÷íî, ìîæíî ñîçäàòü óñëîâèå WHERE, áëàãîäàðÿ êîòîðîìó áóäåò âûïîëíåíî òðåáóåìîå, íî â äàííîì ñëó÷àå ãîðàçäî óäîáíåå èñïîëüçîâàòü îïåðàòîð UNION.
Êàê óæå ãîâîðèëîñü, ïðèìåíåíèå îïåðàòîðà UNION ïîäðàçóìåâàåò ìíîãîêðàòíîå èñïîëüçîâàíèå îïåðàòîðîâ SELECT.
Âíà÷àëå ðàññìîòðèì îòäåëüíûå îïåðàòîðû:
Комбинированные запросы
147
ВВОД
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN ('IL','IN','MI');
ВЫВОД
cust_name
----------Village Toys
Fun4All
The Toy Store
cust_contact
------------John Smith
Jim Jones
Kim Howard
cust_email
-----------sales@villagetoys.com
jjones@fun4all.com
NULL
ВВОД
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_name = 'Fun4All';
ВЫВОД
cust_name
--------Fun4All
Fun4All
cust_contact
-----------Jim Jones
Denise L. Stephens
cust_email
---------jjones@fun4all.com
dstephens@fun4all.com
Анализ
Ïåðâûé îïåðàòîð SELECT âûáèðàåò âñå ñòðîêè, îòíîñÿùèåñÿ ê øòàòàì Èëëèíîéñ, Èíäèàíà è Ìè÷èãàí, ïåðåäàâàÿ
àááðåâèàòóðû ýòèõ øòàòîâ â óñëîâèå IN. Âòîðîé îïåðàòîð
SELECT èñïîëüçóåò ïðîñòóþ ïðîâåðêó íà ðàâåíñòâî, ÷òîáû
íàéòè âñå ìåñòîíàõîæäåíèÿ â òàáëèöàõ êëèåíòà Fun4All.
×òîáû ñêîìáèíèðîâàòü ýòè äâà çàïðîñà, âûïîëíèòå ñëåäóþùåå.
ВВОД
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN ('IL','IN','MI')
UNION
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_name = 'Fun4All';
148
Урок 14
ВЫВОД
cust_name
--------Fun4All
Fun4All
Village
The Toy Store
cust_contact
-----------Denise L.Stephens
Jim Jones
Toys John Smith
Kim Howard
cust_email
---------dstephens@fun4all.com
jjones@fun4all.com
sales@villagetoys.com
NULL
Анализ
Îïåðàòîðû ïðåäûäóùåãî ïðèìåðà ñîñòîÿò èç îáîèõ
ïðåäøåñòâóþùèõ îïåðàòîðîâ SELECT, ðàçäåëåííûõ êëþ÷åâûì ñëîâîì UNION. Îïåðàòîð UNION óêàçûâàåò ÑÓÁÄ âûïîëíèòü îáà îïåðàòîðà SELECT è âûâåñòè ðåçóëüòàòû â âèäå
îäíîãî íàáîðà ðåçóëüòàòîâ çàïðîñà.
Äëÿ ñðàâíåíèÿ ïðèâîäèì òîò æå ñàìûé çàïðîñ, èñïîëüçóþùèé íå îïåðàòîð UNION, à íåñêîëüêî ïðåäëîæåíèé
WHERE:
ВВОД
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN ('IL','IN','MI')
OR cust_name = 'Fun4All';
 íàøåì ïðîñòîì ïðèìåðå ïðèìåíåíèå îïåðàòîðà UNION
ìîæåò îêàçàòüñÿ áîëåå ñëîæíûì, ÷åì èñïîëüçîâàíèå ïðåäëîæåíèÿ WHERE. Îäíàêî åñëè óñëîâèå ôèëüòðàöèè îêàæåòñÿ
áîëåå ñëîæíûì èëè åñëè ïîíàäîáèòñÿ âûáèðàòü äàííûå èç
ìíîãèõ òàáëèö (à íå òîëüêî èç îäíîé), òî îïåðàòîð UNION
ìîæåò çíà÷èòåëüíî óïðîñòèòü ïðîöåññ.
Ограничения оператора UNION
В стандартном SQL не существует ограничений на
число операторов SELECT, которые могут быть скомбинированы посредством операторов UNION. Однако
лучше все же обратиться к документации СУБД и убедиться в том, что она не накладывает каких-либо ограничений на максимально допустимое число операторов.
Комбинированные запросы
Проблемы,
149
связанные с производительностью
В большинстве хороших СУБД используется внутренний оптимизатор запросов, комбинирующий операторы SELECT, прежде чем СУБД начинает их обработку. Теоретически это означает, что, с точки зрения
производительности, нет реальной разницы между
использованием многих предложений WHERE и оператора UNION. Мы говорим “теоретически”, потому что
на практике многие оптимизаторы запросов не всегда выполняют свою работу так хорошо, как следовало бы. Лучшим вариантом было бы протестировать
оба метода и посмотреть, какой из них вам лучше
подходит.
Ïðàâèëà ïðèìåíåíèÿ çàïðîñîâ UNION
Êàê âèäèòå, çàïðîñû UNION î÷åíü ïðîñòû â èñïîëüçîâàíèè. Íî ñóùåñòâóåò íåñêîëüêî ïðàâèë, ÷åòêî óêàçûâàþùèõ,
÷òî èìåííî ìîæåò áûòü îáúåäèíåíî.
„ Çàïðîñ UNION äîëæåí âêëþ÷àòü äâà èëè áîëåå îïåðàòîðîâ SELECT, îòäåëåííûõ îäèí îò äðóãîãî êëþ÷åâûì
ñëîâîì UNION (òàêèì îáðàçîì, åñëè â çàïðîñå èñïîëüçóåòñÿ ÷åòûðå îïåðàòîðà SELECT, äîëæíî áûòü èñïîëüçîâàíî òðè êëþ÷åâûõ ñëîâà UNION).
„ Êàæäûé çàïðîñ â îïåðàòîðå UNION äîëæåí ñîäåðæàòü
îäíè è òå æå ñòîëáöû, âûðàæåíèÿ èëè ñòàòèñòè÷åñêèå ôóíêöèè (êðîìå òîãî, ñòîëáöû äîëæíû áûòü ïåðå÷èñëåíû â îäíîì è òîì æå ïîðÿäêå).
„ Òèïû äàííûõ ñòîëáöîâ äîëæíû áûòü ñîâìåñòèìûìè.
Îíè íå îáÿçàòåëüíî äîëæíû áûòü îäíîãî òèïà, íî îíè
äîëæíû áûòü òîãî òèïà, êîòîðûé ÑÓÁÄ ñìîæåò îäíîçíà÷íî ïðåîáðàçîâàòü (íàïðèìåð, ýòî ìîãóò áûòü ðàçëè÷íûå ÷èñëîâûå òèïû äàííûõ èëè ðàçëè÷íûå òèïû
äàòû).
Ïðè ñîáëþäåíèè ýòèõ îñíîâíûõ ïðàâèë è îãðàíè÷åíèé,
çàïðîñû íà ñîåäèíåíèå ìîæíî èñïîëüçîâàòü äëÿ ðåøåíèÿ
ëþáûõ çàäà÷ ïî âîçâðàùåíèþ äàííûõ.
150
Урок 14
Âêëþ÷åíèå èëè èñêëþ÷åíèå
ïîâòîðÿþùèõñÿ ñòðîê
Âîçâðàòèìñÿ ê îäíîìó èç ïðåäûäóùèõ ðàçäåëîâ “Èñïîëüçîâàíèå îïåðàòîðà UNION” è ðàññìîòðèì èñïîëüçîâàííûå â íåì ïðîñòûå îïåðàòîðû SELECT. Âû ìîæåòå çàìåòèòü,
÷òî, êîãäà îíè âûïîëíÿþòñÿ îòäåëüíî, ïåðâûé îïåðàòîð
SELECT âîçâðàùàåò òðè ñòðîêè, âòîðîé — äâå. Îäíàêî êîãäà
ýòè äâà îïåðàòîðà SELECT êîìáèíèðóþòñÿ ñ UNION, âîçâðàùàþòñÿ òîëüêî ÷åòûðå ñòðîêè, à íå ïÿòü.
Çàïðîñ UNION àâòîìàòè÷åñêè óäàëÿåò âñå ïîâòîðÿþùèåñÿ
ñòðîêè èç íàáîðà ðåçóëüòàòîâ çàïðîñà (èíûìè ñëîâàìè, îí
âåäåò ñåáÿ òî÷íî òàê æå, êàê âåëè áû ñåáÿ íåñêîëüêî ïðåäëîæåíèé WHERE â îäíîì îïåðàòîðå SELECT). Ïîýòîìó çäåñü
ïðèñóòñòâóåò çàïèñü î êëèåíòå Fun4All èç øòàòà Èíäèàíà — ýòà ñòðîêà áûëà âîçâðàùåíà îáîèìè îïåðàòîðàìè
SELECT. Êîãäà æå èñïîëüçîâàëñÿ çàïðîñ UNION, ïîâòîðÿþùàÿñÿ ñòðîêà áûëà óäàëåíà.
Òàêîâî ïîâåäåíèå çàïðîñà UNION ïî óìîë÷àíèþ, íî ïðè
æåëàíèè âû ìîæåòå èçìåíèòü åãî. Åñëè áû òðåáîâàëîñü,
÷òîáû âîçâðàùàëèñü âñå âõîæäåíèÿ ñîîòâåòñòâèé, âàì ñëåäîâàëî áû èñïîëüçîâàòü UNION ALL âìåñòî îïåðàòîðà UNION.
Ðàññìîòðèì ñëåäóþùèé ïðèìåð:
ВВОД
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN ('IL','IN','MI')
UNION ALL
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_name = 'Fun4All';
ВЫВОД
cust_name
----------Village Toys
Fun4All
The Toy
Fun4All
Fun4All
cust_contact
-----------John Smith
Jim Jones
Store Kim Howard
Jim Jones
Denise L.Stephens
cust_email
---------sales@villagetoys.com
jjones@fun4all.com
NULL
jjones@fun4all.com
dstephens@fun4all.com
Комбинированные запросы
151
Анализ
Ïðè èñïîëüçîâàíèè çàïðîñà UNION ALL ÑÓÁÄ íå óäàëÿåò
äóáëèêàòû. Ïîýòîìó â ïðåäûäóùåì ïðèìåðå âîçâðàùåíî
ïÿòü ñòðîê, îäíà èç íèõ ïîâòîðÿåòñÿ äâàæäû.
UNION или WHERE
В начале этого урока мы говорили, что оператор
UNION выполняет то же самое, что и несколько условий WHERE. Оператор UNION ALL является формой
запроса UNION, которая делает то, что не способны
выполнить предложения WHERE. Если вы хотите получить все вхождения соответствий для каждого условия (включая дубликаты), вам следует использовать
оператор UNION ALL, а не WHERE.
Ñîðòèðîâêà ðåçóëüòàòîâ
êîìáèíèðîâàííûõ çàïðîñîâ
Ðåçóëüòàò ïðèìåíåíèÿ îïåðàòîðà SELECT ñîðòèðóåòñÿ ñ
ïîìîùüþ ïðåäëîæåíèÿ ORDER BY. Ïðè êîìáèíèðîâàíèè
çàïðîñîâ ïîñðåäñòâîì UNION òîëüêî îäíî ïðåäëîæåíèå
ORDER ìîæåò áûòü èñïîëüçîâàíî, è îíî äîëæíî ïîÿâèòüñÿ
ïîñëå çàêëþ÷èòåëüíîãî îïåðàòîðà SELECT. Ïðàêòè÷åñêè íå
èìååò ñìûñëà ñîðòèðîâàòü ÷àñòü íàáîðà ðåçóëüòàòîâ îäíèì
ñïîñîáîì, à ÷àñòü — äðóãèì, ïîýòîìó íåñêîëüêî ïðåäëîæåíèé ORDER BY ïðèìåíÿòü íå ðàçðåøàåòñÿ.
 ñëåäóþùåì ïðèìåðå ñîðòèðóþòñÿ ðåçóëüòàòû, ïîëó÷åííûå ïðåäûäóùèì çàïðîñîì UNION:
ВВОД
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state IN ('IL','IN','MI')
UNION
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_name = 'Fun4All'
ORDER BY cust_name, cust_contact;
152
Урок 14
ВЫВОД
cust_name
----------Fun4All
Fun4All
The Toy Store
Village Toys
cust_contact
-----------Denise L.Stephens
Jim Jones
Kim Howard
John Smith
cust_email
---------dstephens@fun4all.com
jjones@fun4all.com
NULL
sales@villagetoys.com
Анализ
Ýòîò çàïðîñ UNION èñïîëüçóåò îäíî ïðåäëîæåíèå ORDER
BY ïîñëå çàêëþ÷èòåëüíîãî îïåðàòîðà SELECT.
Íåñìîòðÿ íà òî ÷òî ORDER BY ÿâëÿåòñÿ ÷àñòüþ òîëüêî
ïîñëåäíåãî îïåðàòîðà SELECT, íà ñàìîì äåëå ÑÓÁÄ áóäåò
èñïîëüçîâàòü åãî äëÿ ñîðòèðîâêè âñåõ ðåçóëüòàòîâ, âîçâðàùåííûõ âñåìè îïåðàòîðàìè SELECT.
Другие типы запроса на соединение
Некоторые СУБД поддерживают два дополнительных
запроса типа UNION. Оператор EXCEPT (иногда называемый MINUS) может быть использован только для
чтения строк, которые существуют в первой таблице,
но не во второй, а оператор INTERSECT можно использовать для чтения строк, которые имеются в обеих таблицах. Однако на практике такие запросы
UNION используются редко, поскольку те же самые
результаты могут быть получены посредством объединений.
Ðåçþìå
 ýòîì óðîêå âû óçíàëè, êàê ìîæíî êîìáèíèðîâàòü çàïðîñû SELECT ïîñðåäñòâîì îïåðàòîðà UNION. Èñïîëüçóÿ
îïåðàòîð UNION, âû ìîæåòå âåðíóòü ðåçóëüòàòû íåñêîëüêèõ
çàïðîñîâ â âèäå îäíîãî êîìáèíèðîâàííîãî çàïðîñà, âêëþ÷àþùåãî èëè èñêëþ÷àþùåãî äóáëèêàòû. Çà ñ÷åò èñïîëüçîâàíèÿ îïåðàòîðà UNION ìîæíî çíà÷èòåëüíî óïðîñòèòü
ñëîæíûå ïðåäëîæåíèÿ WHERE è îäíîâðåìåííî âûáèðàòü
äàííûå èç ìíîãèõ òàáëèö.
Download