SQL Server

Bağlanmış altsuallar

Bağlanmış altsuallar

Siz alt sorğuları istifadə edərkən qurulmuş alt sorğuya xarici alt sorğudan müraciət edə bilərsiniz. Məs, 3 oktyabra olan sifarişçiləri necə tapmalı:

	SELECT *
	FROM Customers C
	WHERE '1999-10-03' IN (
		SELECT odate
		FROM Orders O
		WHERE O.cnum = C.cnum
	)

Nəticə:

	CNUM  CNAME                CITY       RATING  SNUM
	----- -------------------- ---------- ------- -----
	2001  ТОО Рога и копыта    Москва     100     1001
	2002  AО Бендер и К        Одесса     200     1003
	2003  Фирма ХХХ            Рязань     200     1002
	2007  ОАО "ООО"            ТОМСК      100     1004
	2008  ОАО "Валют-транзит"  Караганда  300     1007

Bunlar hamsı necə işləyir?

Yuxarıda istifadə olunan C və O cədvəllərin təxəllüsləridir. Be lə ki sorğunun cnum sətirindəki qiymət dəyişir, və xarici sorğu hər bir daxili sorğunun nəricəsi üçün ayrıca realizə olunmalıdır. Onun üçün daxili realizə olunan xarici sorğu sətiri namizəd sətir adlanır.

Bağlı sorğu ilə realizə olunan sətirin realizə prosesi:

  1. Daxili sorğuda qeyd olunmuş sətiri cədvəldən seçmək. Bu cari namizəd sətir olacaq.
  2. Bu namizəd sətirin qiymətini hələlik buferə salmaq.
  3. Alt sualı realizə etmək. Yazıların seçilməsi üçün namizəd sətirdən istifadə etmək.
  4. III bölmədə realizə olunan daxili alt sorğuların nəticəsi əsasında xarici sorğunun nəticəsini hesablamalı. Namizəd sətirin seçdiyi təuin edilir.
  5. Digər sətirlər üçün əməliyyatı təkrar etməli.

Prinsipcə aşağıdakı kimi birləşmədən də istifadə etmək olar:

	SELECT C.*
	FROM Customers C, Orders O
	WHERE C.cnum = O.cnum AND
		O.odate = '1999.10.03'

Lakin, əgər eyni istifadəci iki və daha artıq sifariş edibsə onda onun adı bir neçə dəfə təkrar olunacaq. Bunu DISTINCT-dən istifadə etməklə dəf etmək olar, lakin bu effektli nəticə deyil. IN operatoru alt sorğu ilə olan variantda alt sorğu olə bir dəfə və təkrarən seçilən dəyişənlər arasında fərq qoymur. Ona görə də DISTINCT lazım deyil.

Tutaq ki biz heç olmasa bir sifarişçisi olan satıcıların ad və nömrələrini bilmək istəyirik:

	SELECT snum, sname
	FROM Salespeople S
	WHERE 1 < (
	   SELECT COUNT(*)
	   FROM Customers c
	   WHERE c.snum = s.snum
	)

Nəticə:

	snum  sname
	----- -------
	1001  Иванов
	1002  Петров

Bağlı sualları özləri ilə müqayisə üçün də istifadə etmək olar. Məs, sifarişçilər üçün orta balın cəmindən yuxarı olan sifarişləri tapmaq olar.

	SELECT *
	FROM Orders O
	WHERE amt > (
	   SELECT AVG( amt )
	   FROM Orders O1
	   WHERE O1.cnum = O.cnum
	)

Nəticə:

	ONUM  ODATE                    AMT        CNUM  SNUM
	----- ------------------------ ---------- ----- -----
	3009  1999-10-04 00:00:00.000  1713.2300  2002  1003
	3010  1999-10-06 00:00:00.000  1309.9500  2004  1002
	3011  1999-10-06 00:00:00.000  9891.8800  2006  1001

Təbii ki bizim balaca VB-də aksər sifarişçilərin yalnız bir sifarişləri var, əksər qiymətlər eyni vaxtda orta olmurlar və ona görə də seçilmirlər.

Bax bu da son. Sizi SQL-də alt suallara aid olan böyük kursu mənimsəməyiniz münasibəti ilə təbrik edirəm. Növbəti addım SQL-in bəzi xüsusi operatorlarının yazılışıdır. Onlar alt sorğuları IN kimi arqument edirlər, lakin IN-dən fərqli olaraq onlar yalnız alt suallarda istifadə oluna bilərlər. Bunlar EXISTS, ANY, ALL operatorlarıdırlar.