========= ÑÎÎÒÍÅÑÅÍÍÛÉ ÏÎÄÇÀÏÐÎÑ ===========

Êîãäà âû èñïîëüçóåòå ïîäçàïðîñû â 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: Íàõîæäåíèå ïðîäàâöîâ ñ ìíîãî÷èñëåíûìè çàêàç÷èêàìè.