========= ÑÎÎÒÍÅÑÅÍÍÛÉ ÏÎÄÇÀÏÐÎÑ ===========
Êîãäà âû èñïîëüçóåòå ïîäçàïðîñû â SQL, âû ìîæåòå
îáðàòèòüñÿ ê âíóòðåííåìó çàïðîñó òàáëèöû â ïðåäëîæåíèè âíåøíåãî çàïðîñà FROM , ñôîðìèðîâàâ - ñîîòíåñåííûé
ïîäçàïðîñ. Êîãäà âû äåëàåòå ýòî, ïîäçàïðîñ âûïîëíÿåòñÿ íåîäíîêðàòíî, ïî îäíîìó ðàçó äëÿ êàæäîé ñòðîêè
òàáëèöû
îñíîâíîãî çàïðîñà. Ñîîòíåñåííûé ïîäçàïðîñ - îäèí èç áîëüøîãî êîëè÷åñòâà òîíêèõ ïîíÿòèé â SQL èç-çà ñëîæíîñòè
â åãî
îöåíêå. Åñëè âû ñóìååòå îâëàäåòü èì, âû íàéäåòå ÷òî îí î÷åíü ìîùíûé, ïîòîìó ÷òî ìîæåò âûïîëíÿòü ñëîæíûå
ôóíêöèè ñ
ïîìîùüþ î÷åíü ëàêîíè÷íûõ óêàçàíèé. Íàïðèìåð, èìååòñÿ îäèí ñïîñîá íàéòè âñåõ çàêàç÷èêîâ â ïîðÿäêàõ íà 3-å
Îêòÿáðÿ (
âûâîä ïîêàçûâàåòñÿ â Ðèñóíêå 11.1 ):
SELECT * FROM Customers outer WHERE 10/03/1990 IN ( SELECT odate FROM Orders
inner WHERE outer.cnum = inner.cnum );
ÊÀÊ ÐÀÁÎÒÀÅÒ ÑÎÎÒÍÅÑÅÍÍÛÉ ÏÎÄÇÀÏÐÎÑ
 âûøåóïîìÿíóòîì ïðèìåðå,
"âíóòðåííèé"(inner) è "âíåøíèé"(outer), ýòî ïñåâäîíèìû. Ìû âûáðàëè ýòè èìåíà äëÿ
áîëüøåé ÿñíîñòè; îíè îòñûëàþò ê çíà÷åíèÿì âíóòðåííèõ è âíåøíèõ çàïðîñîâ, ñîîòâåòñòâåííî. Òàê êàê çíà÷åíèå
â ïîëå cnum
âíåøíåãî çàïðîñà ìåíÿåòñÿ, âíóòðåííèé çàïðîñ äîëæåí âûïîëíÿòüñÿ îòäåëüíî äëÿ êàæäîé ñòðîêè âíåøíåãî
çàïðîñà. Ñòðîêà
âíåøíåãî çàïðîñà äëÿ êîòîðîãî âíóòðåíí-
cnum |
cname |
city |
rating |
snum |
2001 |
Hoffman |
London |
100 |
1001 |
2003 |
Liu |
San Jose |
200 |
1002 |
2008 |
Cisneros |
San Jose |
300 |
1007 |
2007 |
Pereira |
Rome |
100 |
1004 |
Ðèñóíîê 11.1: Èñïîëüçîâàíèå ñîîòíåñåííîãî ïîäçàïðîñà
íèé çàïðîñ êàæäûé ðàç áóäåò âûïîëíåí, íàçûâàåòñÿ - òåêóùåé ñòðîêîé-êàíäèäàòîì. Ñëåäîâàòåëüíî,
ïðîöåäóðà îöåíêè
âûïîëíÿåìîé ñîîòíåñåííûì ïîäçàïðîñîì - ýòî:
1. Âûáðàòü ñòðîêó èç òàáëèöû èìåíîâàííîé â âíåøíåì çàïðîñå. Ýòî áóäåò òåêóùàÿ ñòðîêà-êàíäèäàò.
2. Ñîõðàíèòü çíà÷åíèÿ èç ýòîé ñòðîêè-êàíäèäàòà â ïñåâäîíèìå ñ èìåíåì â ïðåäëîæåíèè FROM âíåøíåãî çàïðîñà.
3. Âûïîëíèòü ïîäçàïðîñ. Âåçäå, ãäå ïñåâäîíèì äàííûé äëÿ âíåøíåãî çàïðîñà íàéäåí ( â ýòîì ñëó÷àå
"âíåøíèé" ), èñïîëüçîâàòü çíà÷åíèå äëÿ òåêóùåé ñòðîêè-êàíäèäàòà.
Èñïîëüçîâàíèå çíà÷åíèÿ èç ñòðîêè-êàíäèäàòà âíåøíåãî
çàïðîñà â ïîäçàïðîñå íàçûâàåòñÿ - âíåøíåé ññûëêîé.
4. Îöåíèòü ïðåäèêàò âíåøíåãî çàïðîñà íà îñíîâå ðåçóëüòàòîâ
ïîäçàïðîñà âûïîëíÿåìîãî â øàãå 3. Îí îïðåäåëÿåòü - âûáèðàåòñÿ ëè ñòðîêà-êàíäèäàò äëÿ âûâîäà.
5. Ïîâòîðèòü ïðîöåäóðó
äëÿ ñëåäóþùåé ñòðîêè-êàíäèäàòà òàáëèöû, è òàê äàëåå ïîêà âñå ñòðîêè òàáëèöû íå áóäóò ïðîâåðåíû.
 âûøåóïîìÿíóòîì
ïðèìåðå, SQL îñóùåñòâëÿåò ñëåäóþùóþ ïðîöåäóðó:
1. Îí âûáèðàåò ñòðîêó Hoffman èç òàáëèöû Çàêàç÷èêîâ.
2. Ñîõðàíÿåò ýòó
ñòðîêó êàê òåêóùóþ ñòðîêó-êàíäèäàò ïîä ïñåâäîíèìîì - "âíåøíèì".
3. Çàòåì îí âûïîëíÿåò ïîäçàïðîñ. Ïîäçàïðîñ
ïðîñìàòðèâàåò âñþ òàáëèöó Ïîðÿäêîâ ÷òîáû íàéòè ñòðîêè ãäå çíà÷åíèå cnum ïîëå - òàêîå æå êàê çíà÷åíèå outer.cnum,
êîòîðîå
â íàñòîÿùåå âðåìÿ ðàâíî 2001, - ïîëå cnum ñòðîêè Hoffmanà. Çàòåì îí èçâëåêàåò ïîëå odate èç êàæäîé ñòðîêè
òàáëèöû
Ïîðÿäêîâ äëÿ êîòîðîé ýòî âåðíî, è ôîðìèðóåò íàáîð çíà÷åíèé ïîëÿ odate.
4. Ïîëó÷èâ íàáîð âñåõ çíà÷åíèé ïîëÿ odate, äëÿ
ïîëÿ cnum = 2001, îí ïðîâåðÿåò ïðåäèêàò îñíîâíîãî çàïðîñà ÷òîáû âèäåòü èìååòñÿ ëè çíà÷åíèå íà 3 Îêòÿáðÿ
â ýòîì íàáîðå.
Åñëè ýòî òàê(à ýòî òàê), òî îí âûáèðàåò ñòðîêó Hoffmanà äëÿ âûâîäà åå èç îñíîâíîãî çàïðîñà.
5. Îí ïîâòîðÿåò âñþ
ïðîöåäóðó, èñïîëüçóÿ ñòðîêó Giovanni êàê ñòðîêó-êàíäèäàòà, è çàòåì ñîõðàíÿåò ïîâòîðíî ïîêà êàæäàÿ ñòðîêà
òàáëèöû
Çàêàç÷èêîâ íå áóäåò ïðîâåðåíà.
Êàê âû ìîæåòå âèäåòü, âû÷èñëåíèÿ êîòîðûå SQL âûïîëíÿåò ñ ïîìîùüþ ýòèõ
ïðîñòûõ
èíñòðóêöèé - ýòî ïîëíûé êîìïëåêñ. Êîíå÷íî, âû ìîãëè áû ðåøèòü òó æå ñàìóþ ïðîáëåìó èñïîëüçóÿ îáüåäèíåíèå,
ñëåäóþùåãî âèäà ( âûâîä äëÿ ýòîãî çàïðîñà ïîêàçûâàåòñÿ â Ðèñóíêå 11.2 ):
SELECT * FROM Customers first, Orders second
WHERE first.cnum = second.cnum AND second.odate = 10/03/1990;
Îáðàòèòå âíèìàíèå ÷òî Cisneros áûë âûáðàí
äâàæäû, ïî
îäíîìó ðàçó äëÿ êàæäîãî ïîðÿäêà êîòîðûé îí èìåë äëÿ äàííîé äàòû. Ìû ìîãëè áû óñòðàíèòü ýòî èñïîëüçóÿ
SELECT
DISTINCT âìåñòî ïðîñòî SELECT. Íî ýòî íåîáÿçàòåëüíî â âàðèàíòå ïîäçàïðîñà. Îïåðàòîð IN, èñïîëüçóåìûé â
âàðèàíòå
ïîäçàïðîñà, íå äåëàåò íèêàêîãî ðàçëè÷èÿ ìåæäó çíà÷åíèÿìè êîòîðûå âûáèðàþòñÿ ïîäçàïðîñîì îäèí ðàç è çíà÷åíèÿìè
êîòîðûå âûáèðàþòñÿ íåîäíîêðàòíî. Ñëåäîâàòåëüíî DISTINCT íåîáÿçàòåëåí.
cnum |
cname |
1001 |
Peel |
1002 |
Serres |
Ðèñóíîê 11. 2 Èñïîëüçîâàíèå îáüåäèíåíèÿ âìåñòî ñîîòíåñåííîãî ïîäçàïðîñà
Ïðåäïîëîæèì ÷òî ìû õîòèì âèäåòü èìåíà è íîìåðà âñåõ
ïðîäàâöîâ êîòîðûå èìåþò áîëåå îäíîãî çàêàç÷èêà. Ñëåäóþùèé çàïðîñ âûïîëíèò ýòî äëÿ âàñ ( âûâîä ïîêàçûâàåòñÿ
â
Ðèñóíêå 11.3 ):
SELECT snum, sname FROM Salespeople main WHERE 1 < ( SELECT COUNT (*) FROM Customers WHERE snum = main.snum );
Îáðàòèòå âíèìàíèå ÷òî ïðåäëîæåíèå FROM ïîäçàïðîñà â ýòîì ïðèìåðå íå èñïîëüçóåò ïñåâäîíèì. Ïðè
îòñóòñòâèè èìåíè òàáëèöû èëè ïðåôèêñà ïñåâäîíèìà, SQL ìîæåò äëÿ íà÷àëà ïðèíÿòü, ÷òî ëþáîå ïîëå âûâîäèòñÿ
èç òàáëèöû ñ èìåíåì óêàçàííûì â ïðåäëîæåíèè FROM òåêóùåãî çàïðîñà. Åñëè ïîëå ñ ýòèì èìåíåì îòñóòñòâóåò(
â íàøåì ñëó÷àå -
snum ) â òîé òàáëèöå, SQL áóäåò ïðîâåðÿòü âíåøíèå çàïðîñû. Èìåííî ïîýòîìó, ïðåôèêñ èìåíè òàáëèöû îáû÷íî
íåîáõîäèì â
ñîîòíåñåííûõ ïîäçàïðîñàõ - äëÿ îòìåíû ýòîãî ïðåäïîëîæåíèÿ. Ïñåâäîíèìû òàêæå ÷àñòî çàïðàøèâàþòñÿ ÷òîáû
äàâàòü âàì
âîçìîæíîñòü ññûëàòüñÿ ê òîé æå ñàìîé òàáëèöå âî âíóòðåííåì è âíåøíåì çàïðîñå áåç êàêîé-ëèáî íåîäíîçíà÷íîñòè.
cnum |
cname |
city |
rating |
snum |
2001 |
Hoffman |
London |
100 |
1001 |
2003 |
Liu |
San Jose |
200 |
1002 |
2008 |
Cisneros |
San Jose |
300 |
1007 |
2007 |
Pereira |
Rome |
100 |
1004 |
Ðèñóíîê 11.3: Íàõîæäåíèå ïðîäàâöîâ ñ ìíîãî÷èñëåíûìè çàêàç÷èêàìè.