SQL-də iç içə və əlaqəli alt sorğular, EXISTS predikatı. EXISTS operatorundan istifadə mövcud funksiyadan istifadə edərək Sorğular

MÖVCUD YERDƏ

Alt sorğu bir və ya bir neçə cərgənin mövcudluğu üçün yoxlanılır. Əgər sorğuya ən azı bir sətir uyğun gəlirsə, TRUE məntiqi dəyəri qaytarılır. İsteğe bağlı DEYİL açar sözü təyin edildikdə, alt sorğu heç bir uyğun sətir qaytarmırsa, TRUE Boolean dəyəri qaytarılır.

alt sorğu

Tam formalaşmış alt sorğu əsasında nəticədə əldə edilən məlumat dəsti alınır.

Ümumi qaydalar

EXISTS operatoru əsas sorğunun alt sorğusunda bir və ya bir neçə cərgənin mövcudluğunu yoxlayır.

MÖVCUD OLMAYAN İŞLƏRDƏN * SEÇİN (SEÇ * işçinin HARƏDƏ jobs.job_id=employye.job_id);

Bu nümunə əlavə NOT açar sözündən istifadə edərək qeydlər alt sorğusunu yoxlayır. Aşağıdakı nümunə əsas nəticə dəstini əldə etmək üçün alt sorğuda xüsusi qeydləri axtarır.

MÖVCUD OLAN müəlliflərdən au_lname SEÇİN (SEÇ * FROM publishers WHERE authors.city=publishers.city);

Bu sorğu naşirlərlə eyni şəhərdə yaşayan müəlliflərin soyadlarını (au_lname) qaytarır. Nəzərə alın ki, alt sorğuda ulduz işarəsindən istifadə edə bilərsiniz, çünki alt sorğu TRUE mantiqi dəyəri olan yalnız bir qeyd qaytarmalıdır. Belə hallarda sütunların əhəmiyyəti yoxdur. Əsas məqam simin mövcudluğudur.

Bir çox sorğularda EXISTS operatoru HƏR HƏR ilə eyni funksiyanı yerinə yetirir. EXISTS operatoru adətən əlaqəli sorğularla istifadə edildikdə ən səmərəli olur.

EXISTS operatoru semantik olaraq HƏR operatora ekvivalentdir.

EXISTS ifadəsindəki alt sorğu adətən iki növ axtarışdan birini həyata keçirir. Birinci seçim joker simvoldan - ulduzdan istifadə etməkdir (məsələn, SELECT * FROM...), bu halda siz heç bir xüsusi sütun və ya dəyər əldə etmirsiniz. Buradakı ulduz işarəsi "hər hansı bir sütun" deməkdir. İkinci seçim alt sorğuda yalnız bir xüsusi sütun seçməkdir (məsələn, SELECT aujd FROM). Bəzi fərdi platformalar birdən çox sütunda alt sorğulara icazə verir (məsələn, SELECT aujd, aujname FROM...). Bununla belə, bu xüsusiyyət nadirdir və digər platformalara daşınması lazım olan kodda ondan qaçınmaq lazımdır.

Platformalar arasındakı fərqlər

Bütün platformalar yuxarıda təsvir etdiyimiz formada EXISTS operatorunu dəstəkləyir.

“Əvvəllər daha asan idi” — SQL-də növbəti sorğunu optimallaşdırmaq üçün oturarkən düşündüm idarəetmə studiyası. MySQL altında yazanda hər şey həqiqətən daha sadə idi - ya işləyir, ya da işləmir. Ya yavaşlayır, ya da getmir. Bütün problemlərimi izah etdim, daha heç nə lazım olmadı. İndi sorğuların və prosedurların/funksiyaların işlənib hazırlanması, sazlanması və optimallaşdırılması üçün güclü mühitim var və bütün bu qarışıqlıq mənim fikrimcə daha çox problemlər yaradır. Və niyə hamısı? Çünki daxili sorğu optimallaşdırıcısı pisdir. MySQL və PostgreSQL-də yazıram

a, b, c arasından * seçin, burada a.id = b.id, b.id = c.id

və tabletlərin hər birində ən azı 5k xətt olacaq - hər şey donacaq. Və Allaha şükür! Çünki əks halda tərtibatçıda ən yaxşı halda düzgün yazmaq üçün tənbəllik yaranır, ən pis halda isə heç nə etdiyini başa düşmür! Axı, MSSQL-də eyni sorğu eyni şəkildə işləyəcək

a.id-də b birləşməsindən * seçin = b.id qoşulma c b.id = c.id

Daxili optimallaşdırıcı lazımsız sorğunu darayacaq və hər şey qaydasında olacaq.

O, həmçinin nə etmək daha yaxşı olduğuna özü qərar verəcək - mövcud olmaq və ya qoşulmaq və daha çox. Və hər şey mümkün qədər optimal şəkildə işləyəcək.

Yalnız bir AMA var. Bir nöqtədə, optimallaşdırıcı büdrəyəcək mürəkkəb sorğu və keçir və sonra böyük bir problemlə qarşılaşırsınız. Və onu dərhal ala bilməyəcəksiniz, ancaq masaların çəkisi kritik kütləyə çatdıqda.

Beləliklə, məqalənin əsas nöqtəsinə. mövcuddur və çox ağır əməliyyatlardadır. Bu əslində ayrı bir alt sorğudur hər biri üçün nəticə xətləri. Əgər yuva da varsa, o, ümumiyyətlə işıqları söndürür. 1, 10, 50 sətir qaytarıldıqda hər şey yaxşı olacaq. Siz fərqi hiss etməyəcəksiniz və bəlkə də qoşulma daha yavaş olacaq. Amma 500 çıxarılanda problemlər başlayır. Bir sorğuda 500 alt sorğu ciddidir.

Baxmayaraq ki, insan anlayışı nöqteyi-nəzərindən, var və var daha yaxşıdır, lakin 50-dən çox sətir qaytaran sorğular üçün vaxt xərcləri baxımından onlar məqbul deyil.

Rezervasiya etmək lazımdır ki, təbii ki, haradasa azalırsa, harasa gəlməlidir. Bəli, qoşulma daha çox yaddaş tələb edir, çünki bütün dəyərlər cədvəlini bir anda saxlamaq və onunla işləmək hər cərgə üçün alt sorğuları yerinə yetirməkdən daha bahalıdır, yaddaşı tez boşaltır. Xüsusi olaraq sorğuya baxmaq və vaxt xatirinə əlavə yaddaşdan istifadənin kritik olub-olmadığını ölçmək lazımdır.

Tam bənzətmələrə misallar verəcəyəm. Ümumiyyətlə, mən hələ birləşmələr kaskadına çevrilə bilməyən belə bir mürəkkəblik dərəcəsinə malik sorğularla qarşılaşmamışam. Bir gün çəkə bilər, amma hər şey üzə çıxa bilər.

a.id-də olan yerdən * seçin (b-dən id-i seçin) mövcud yerdən * seçin (b-dən yuxarı 1 1-i seçin, burada b.id = a.id) a.id = b-də b birləşməsindən * seçin. id a.id olmayan yerdən * seçin (b-dən id-i seçin) mövcud olmayan yerdən * seçin (b-dən yuxarı 1 1-i seçin, burada b.id = a.id) a-da sol birləşmədən b seçin. id = b.id burada b.id sıfırdır

Təkrar edirəm - MSSQL optimallaşdırıcısı bu nümunələri optimallaşdırır maksimum performans və heç vaxt belə sadə istəkləri olan axmaq insanlar olmayacaq.

İndi yenidən yazılmalı olan real sorğu nümunəsini nəzərdən keçirək, çünki o, sadəcə olaraq bəzi nümunələrdə donmuşdur (struktur çox sadələşdirilmişdir və anlayışlar dəyişdirilmişdir, verilənlər bazası strukturunun bəzi qeyri-optimallığından qorxmağa ehtiyac yoxdur). ).

Fərqli hesablardakı bütün dublikat "məhsulları" çıxartmalısınız, əgər varsa, məhsulun, onun qrupunun və ana qrupun parametrlərinə diqqət yetirməlisiniz.

PRODUCT-lərdən d.PRODUCT_ID seçin, PRODUCT_GROUP sg sola qoşulun M_PG_DEPENDENCY sd-də (sg.PRODUCT_GROUP_ID = sd.M_PG_DEPENDENCY_CHILD_ID), PRODUCT d, PRODUCT_GROUP dg solda M_PG_DEPENDENCY qoşulun (MDROCT_GROUP dg solda M_PG_DEPENDENCY qoşulun END_PGIDPg). .M_PG_DEPENDENCY_CHILD_ID) burada s.PRODUCT_GROUP_ID=sg .PRODUCT_GROUP_ID və d.PRODUCT_GROUP_ID=dg.PRODUCT_GROUP_ID və sg.PRODUCT_GROUP_PERSPEC=dg.PRODUCT_GROUP_PERSPEC və sg.PRODUCT_GROUP_NAME=dg.PRODUCT_GROUP_NAME=dg.PRODUCT_NAME=dg.PRODUCT_NAME_s və. PRODUCT_TYPE=d.PRODUCT_TYPE və s.PRODUCT_IS_SECURE=d.PRODUCT_IS_SECURE və s.PRODUCT_MULTISELECT=d.PRODUCT_MULTISELECT və dg.PRODUCT_GROUP_IS_TMPL=0 və ((sd.M_PG_DEPENDENCY_CHILD_ID null və dd.M_PG_DEPENDENCY_CHILD_ID sıfırdır) və ya PRODUCT1g-dən mövcuddur (dg.PRODUCT_GROUPG) burada sd.M_PG_DEPENDENCY_PARENT_ID = sg1.PRODUCT_GROUP_ID və dd .M_PG_DEPENDENCY_PARENT_ID = dg1.PRODUCT_GROUP_ID və sg1.PRODUCT_GROUP_PERSPEC=dg1.PRODUCT_GROUP_PERSPEC və sg1.PRODUCT_GROUP_NAME=dg1.PRODUCT_NAME və))

Optimizator imtina etdikdə belə olur. Və hər bir sətir üçün verilənlər bazasını öldürən ağır bir varlıq icra edildi.

PRODUCT-dən d.PRODUCT_ID seçin PRODUCT-ə qoşulun d s.PRODUCT_TYPE=d.PRODUCT_TYPE və s.PRODUCT_NAME=d.PRODUCT_NAME və s.PRODUCT_IS_SECURE=d.PRODUCT_IS_SECURE və s.PRODUCT_SELECT_s.PRODUCTROUPROPMG-də qoşulun. s.PRODUCT_GROUP_ID= sg.PRODUCT_GROUP_ID, d.PRODUCT_GROUP_ID=dg.PRODUCT_GROUP_ID-də PRODUCT_GROUP dg-ə qoşulun və sg.PRODUCT_GROUP_NAME=dg.PRODUCT_GROUP_NAME və sg.PRODUCT_GROUP_GPERDEGSPEC=Sg.PRODUCT_GROUP_PERDECD-dən ayrıldı. sg.PRODUCT_GROUP_ID-də Y sd = sd.M_PG_DEPENDENCY_CHILD_ID, dg-də M_PG_DEPENDENCY dd-ə qoşuldu. PRODUCT_GROUP_ID = dd.M_PG_DEPENDENCY_CHILD_ID sgp-də PRODUCT_GROUP sgp-ə qoşuldu.PRODUCT_GROUP_ID = sd.M_PG_DEPENDENCY_PARENT_ID çıxdı PRODUCT_GROUP dgp-ə sgp-də qoşulun.ENDENCY_PARENT_ID çıxdı. və sgp.PRODUC T_GROUP_NAME = dgp.PRODUCT_GROUP_NAME və boşdur(sgp.PRODUCT_GROUP_IS_TMPL, 0) = boşdur( dgp.PRODUCT_GROUP_IS_TMPL, 0) burada (sd.M_PG_DEPENDENCY_CHILD_ID null və dd.M_PG_DEPENDENCY_CHILD_ID null) və ya (sgp.PRODUCT_GROUP_NAME null deyil və dgp.PRODUCT_go null deyil)

Bu çevrilmələrdən sonra görünüşün performansı tapılan məhsulların sayı ilə eksponent olaraq artdı. Daha doğrusu, axtarış vaxtı matçların sayından praktiki olaraq müstəqil olaraq qaldı və həmişə çox kiçik idi. Olmalı olduğu kimi.

Bu, MSSQL optimallaşdırıcısına güvənməyin necə qəddar zarafat edə biləcəyinin bariz nümunəsidir. Ona etibar etməyin, tənbəl olmayın, əl ilə qoşulun, hər dəfə müəyyən bir vəziyyətdə nəyin daha yaxşı olduğunu düşünün - var, var və ya qoşulun.

SQL dilinin EXISTS predikatı məntiqi tapşırığı yerinə yetirir. IN SQL sorğuları bu predikat formanın ifadələrində işlənir

MÖVCUDDUR (SEÇİN * TABLE_NAMEDƏN ...).

Sorğu şərtə uyğun gələn bir və ya bir neçə sətir tapdıqda bu ifadə doğru, heç bir sətir tapılmadıqda isə yalan qaytarır.

MÖVCUD OLMAQ üçün isə əksinədir. İfadə

MÖVCUD DEYİL (CƏDVƏL_NAMEDƏN * SEÇİN ...)

sorğuda heç bir sıra tapılmadıqda doğru, ən azı bir sətir tapıldıqda isə yalan qaytarır.

SQL EXISTS predikatı ilə ən sadə sorğular

Nümunələrdə biz kitabxana verilənlər bazası və onun “İstifadə olunan kitab” (BOOKINUSE) və “İstifadəçi” (USER) cədvəlləri ilə işləyirik. Hələlik bizə yalnız “İstifadə olunan kitab” cədvəli (BOOKINUSE) lazımdır.

MüəllifBaşlıqPubyearInv_Noİstifadəçi adı
TolstoyMüharibə və Sülh2005 28 65
ÇexovAlbalı bağı2000 17 31
ÇexovSeçilmiş hekayələr2011 19 120
ÇexovAlbalı bağı1991 5 65
İlf və PetrovOn iki stul1985 3 31
MayakovskiŞeirlər1983 2 120
ParsnipDoktor Jivaqo2006 69 120
Tolstoybazar günü2006 77 47
TolstoyAnna Karenina1989 7 205
PuşkinKapitanın qızı2004 25 47
Qoqoloynayır2007 81 47
ÇexovSeçilmiş hekayələr1987 4 205
ParsnipSevimlilər2000 137 18

Misal 1. Tolstoyun kitabları verilmiş və Çexovun kitabları da verilmiş istifadəçilərin şəxsiyyət vəsiqələrini müəyyənləşdirin. Xarici sorğuda Tolstoyun kitabları verilmiş istifadəçilər haqqında məlumatlar seçilir, EXISTS predikatı isə daxili sorğuda yoxlanılan əlavə şərt - Çexovun kitabları verilmiş istifadəçilər haqqında məlumat verilir. Daxili sorğuda əlavə şərt xarici və daxili sorğulardan olan istifadəçi ID-lərinin uyğun olmasıdır: User_ID=tols_user.user_id. Müraciət aşağıdakı kimi olacaq:

Bu sorğu aşağıdakı nəticəni qaytaracaq:

EXISTS və IN predikatları arasındakı fərqlər

EXISTS predikatı olan sorğulara ilk baxışda onun eyni olduğu təəssüratı yarana bilər. predikat IN. Bu səhvdir. Baxmayaraq ki, onlar çox oxşardırlar. IN predikatı öz arqumentində göstərilən diapazondan dəyərləri axtarır və belə dəyərlər varsa, bu diapazona uyğun gələn bütün sətirlər seçilir. EXISTS predikatının nəticəsi, arqumentdə göstərilənlərə ümumiyyətlə uyğun gələn hər hansı dəyərlərin olub-olmaması sualına "bəli" və ya "yox" cavabıdır. Bundan əlavə, IN predikatından əvvəl diapazondakı dəyərlərə uyğun sətirləri axtarmaq üçün sütunun adı verilir. EXISTS predikatı ilə IN predikatı arasındakı fərqi və IN predikatından istifadə etməklə həll olunan məsələni göstərən nümunəyə baxaq.

Misal 4. Kitabları istifadəçiyə ID 31 ilə verilmiş müəlliflər tərəfindən kitablar verilmiş istifadəçilərin şəxsiyyət vəsiqələrini müəyyən edin. Sorğu aşağıdakı kimi olacaq:

İstifadəçi adı
120
65
205

Daxili sorğu (IN-dən sonra) müəllifləri seçir: Çexov; İlf və Petrov. Xarici sorğu bu müəlliflər tərəfindən kitablar verilmiş bütün istifadəçiləri seçir. Görürük ki, EXISTS predikatından fərqli olaraq, IN predikatından əvvəl sütunun adı gəlir, bu halda - Müəllif.

EXISTS predikatı və əlavə şərtləri olan sorğular

Əgər sorğuda EXISTS predikatına əlavə olaraq, siz ən azı bir əlavə şərt tətbiq etsəniz, məsələn, məcmu funksiyalar, onda belə sorğular sadə verilənlərin təhlili üçün xidmət edə bilər. Bunu aşağıdakı nümunə ilə nümayiş etdirək.

Misal 5. Pasternak tərəfindən ən azı bir kitab verilmiş və 2-dən çox kitab verilmiş istifadəçilərin şəxsiyyət vəsiqələrini müəyyənləşdirin. Aşağıdakı sorğunu yazırıq, burada birinci şərt EXISTS predikatı ilə iç içə sorğu ilə müəyyən edilir və HAVING operatoru ilə ikinci şərt həmişə iç içə sorğudan sonra gəlməlidir:

Müraciətin nəticəsi:

İstifadəçi adı
120

BOOKINUSE cədvəlindən göründüyü kimi, Pasternakın kitabı da ID 18 ilə istifadəçiyə verilib, lakin ona yalnız bir kitab verilib və nümunəyə daxil edilməyib. Əgər COUNT funksiyasını oxşar sorğuya yenidən tətbiq etsəniz, lakin bu dəfə seçilmiş sətirləri saymaq üçün (özünüz bunu məşq edin), Pasternakın kitablarını oxuyan neçə istifadəçinin digər müəlliflərin kitablarını da oxuduğu barədə məlumat əldə edə bilərsiniz. Bu, artıq məlumatların təhlili sahəsindəndir.

EXISTS predikatı olan sorğular iki cədvəldə

EXISTS predikatı olan sorğular birdən çox cədvəldən məlumatları əldə edə bilər. Bir çox problemi eyni nəticə ilə həll etmək olar JOIN operatoru, lakin bəzi hallarda EXISTS-dən istifadə daha az çətin sorğu yaratmağa imkan verir. Yaranan cədvəldə yalnız bir cədvəlin sütunları olacağı hallarda EXISTS-dən istifadə etmək daha məqsədəuyğundur.

Aşağıdakı misalda eyni verilənlər bazasından BOOKINUSE cədvəlindən əlavə sizə USER cədvəli də lazım olacaq.

Sorğunun nəticəsi aşağıdakı cədvəl olacaq:

Müəllif
Çexov
Mayakovski
Parsnip

JOIN operatorundan istifadə edərkən, birdən çox cədvəlin olduğu hallarda, cədvəlləri birləşdirən düymələrin dəyərlərinin uyğunluğunu yoxlamaq üçün cədvəl ləqəblərindən istifadə etməlisiniz. Bizim nümunəmizdə cədvəl ləqəbləri bk və us, cədvəlləri birləşdirən açar isə User_ID-dir.

İkidən çox cədvəlin birləşmələrində EXISTS predikatı

İndi biz daha ətraflı görəcəyik ki, nə üçün EXISTS-dən istifadə etmək daha məqsədəuyğundur, nəticədə ortaya çıxan cədvəldə yalnız bir cədvəldən sütunlar olacaq.

Biz “Əmlak” bazası ilə işləyirik. Sövdələşmə cədvəlində əqdlər haqqında məlumatlar var. Tapşırıqlarımız üçün bu cədvəldə əməliyyatın növü - satış və ya icarəyə dair məlumatları olan Növ sütunu vacib olacaq. Obyekt cədvəlində obyektlər haqqında məlumatlar var. Bu cədvəldə bizə Boolean formatında lodjiya və ya balkonun olması barədə məlumatları ehtiva edən Otaqların (otaqların sayı) və LogBalc sütunlarının dəyərlərinə ehtiyacımız olacaq: 1 (bəli) və ya 0 (yox). Müştəri, Menecer və Sahib cədvəllərində müvafiq olaraq müştərilər, şirkət menecerləri və mülkiyyət sahibləri haqqında məlumatlar var. Bu cədvəllərdə FName və LName müvafiq olaraq ad və soyadlardır.

Misal 7. Lodjiya və ya balkonu olmayan mülkləri almış və ya icarəyə götürmüş müştəriləri müəyyənləşdirin. EXISTS predikatının iki cədvəlin birləşməsinin nəticəsinə çıxışı təyin etdiyi aşağıdakı sorğunu yazırıq:

Sütunlar ulduz operatorundan istifadə etməklə Müştəri cədvəlindən seçildiyi üçün bu cədvəlin bütün sütunları EXISTS predikatı ilə müəyyən edilmiş şərtə uyğun gələn klientlərin sayı qədər cərgəyə malik olacaq. Qoşulmasına alt sorğu ilə daxil olan cədvəllərdən heç bir sütun çıxarmağa ehtiyacımız yoxdur. Buna görə də, maşın vaxtına qənaət etmək üçün yalnız bir sütun alınır. Bunun üçün SELECT sözündən sonra vahid yazılır. Eyni texnika aşağıdakı nümunələrdə sorğularda istifadə olunur.

Özünüz EXISTS predikatı ilə SQL sorğusu yazın və sonra həll yoluna baxın

EXISTS predikatı ilə birlikdə SQL sorğularını yazmağa davam edirik

Misal 9.İcarəyə verilmiş obyektlərin sahiblərini müəyyənləşdirin. Aşağıdakı sorğunu yazırıq, burada EXISTS predikatı da iki cədvəlin birləşməsinin nəticəsinə çıxışı müəyyən edir:

Əvvəlki nümunədə olduğu kimi, xarici sorğunun əldə etdiyi cədvəldəki bütün sahələr qaytarılacaq.

Misal 10. Mülkiyyətləri menecer Savelyev tərəfindən idarə olunan sahiblərin sayını müəyyənləşdirin. Xarici sorğunun üç cədvəlin birləşməsinə daxil olduğu bir sorğu yazırıq və EXISTS predikatı yalnız bir cədvələ girişi təyin edir:

Bütün sorğular mövcud verilənlər bazası ilə yoxlanılır. Uğurlu istifadə!

Əlaqəli verilənlər bazaları və SQL dili

Novosibirsk Dövlət İqtisadiyyat və İdarəetmə Akademiyası

FƏRZİNDƏN LABORATORİYA PRAKTİKUMU

"MƏLUMAT BAZASI"

7 saylı laboratoriya işi

"Əsasların dili SQL məlumatları: məlumatların manipulyasiya əmrləri»

NOVOSİBİRSK 2000

SQL Structured Query Language üçün qısaldılmışdır. Dilin adından aydın olur ki, onun əsas məqsədi verilənlər bazasından məlumat əldə etmək üçün sorğular yaratmaqdır. SQL dilinin tərkib hissəsi olan DML verilənlərin manipulyasiya dilinin əsasını verilənlərin əldə edilməsi əmrləri təşkil edir. Bununla belə, DML verilənlər bazasından məlumat əldə etmək üçün sadəcə əmrlərdən daha çox şeydən ibarətdir. Məlumatların dəyişdirilməsi, məlumatların idarə edilməsi və başqaları üçün əmrlər də var.

Laboratoriya işi DML dilinin əsas alətlərini araşdırır. Davam edir laboratoriya işi biz SQL2 standartına sadiq qalacağıq.

SQL böyük bir dil olduğuna görə biz yalnız əsas əmrləri nəzərdən keçirəcəyik. Müxtəlif xüsusi SQL alətləri sonrakı laboratoriyalarda əhatə olunur.

Laboratoriya işlərinin yerinə yetirilməsi üçün relyasiyalı verilənlər modelinin əsasları, relyasiya cəbri və relyasiya hesablamasının əsasları və MS SQL Server DBMS ilə iş prinsipləri haqqında biliklər tələb olunur.

Laboratoriya işlərinin yerinə yetirilməsi nəticəsində siz SQL dili komandalarından istifadə etməklə verilənlərin manipulyasiya üsullarını mənimsəyəcək, MS SQL Server DBMS-də həyata keçirilən dilin dialektini nəzərdən keçirəcəksiniz.

GİRİŞ

SQL həm sorğu yaratmaq, həm də verilənlər bazasını yeniləmək üçün geniş məlumat manipulyasiya imkanlarını ehtiva edir. Bu imkanlar relyasiya modelinin tələblərinə uyğun gələn fiziki strukturuna deyil, yalnız verilənlər bazasının məntiqi strukturuna əsaslanır.

SQL sintaksisinin orijinal strukturu Codd-un relational hesablamalarına əsaslanırdı (və ya heç olmasa belə görünürdü). Əlaqəli cəbrdə dəstəklənən yeganə əməliyyat birləşmə idi.

Əvvəlki standartda işlənmiş relyativ hesaba bənzər sintaksisə əlavə olaraq, SQL2 əməliyyatların birləşməsini, kəsişməsini, fərqini və birləşməsini birbaşa həyata keçirir. Seçmə, layihə və məhsul əməliyyatları demək olar ki, birbaşa dəstəkləndi (və davam edir), bölmə və təyinat əməliyyatları isə daha çətin formada dəstəklənir.

Əvvəlcə SQL sorğu dilini, sonra isə onun məlumatların daxil edilməsi və dəyişdirilməsi əməliyyatlarını təsvir edəcəyik. Məlumatların dəyişdirilməsi əməliyyatları sonuncu olaraq təsvir ediləcək, çünki onların strukturu müəyyən dərəcədə sorğu dilinin strukturundan asılıdır.

Sadə sorğular

Bizim üçün sadə sorğu verilənlər bazasında yalnız bir cədvələ daxil olan sorğu olacaq. Sadə sorğular bizə SQL-in əsas strukturunu təsvir etməyə kömək edəcək.

Sadə sorğu. Yalnız bir verilənlər bazası cədvəlinə daxil olan sorğu.

Sorğu: Kim suvaqçı işləyir?

WHERE SKILL_TYPE = "Sıvaqçı"

Nəticə:

G.Rikover

Bu sorğu ən ümumi üçü göstərir ifadələr SQL: SELECT, FROM və HARADA. Nümunəmizdə onları müxtəlif sətirlərdə yerləşdirsək də, hamısı eyni sətirdə görünə bilər. Onlar həmçinin fərqli şəkildə girintilənə bilər və ifadələr içərisindəki sözlər ixtiyari sayda boşluqla ayrıla bilər. Gəlin hər bir ifadənin xüsusiyyətlərinə baxaq.

seçin. SELECT bəndi nəticədə ortaya çıxan cədvəldə görünməli olan sütunları sadalayır. Bunlar həmişə bəzi əlaqəli cədvəlin sütunlarıdır. Bizim nümunəmizdə nəticə cədvəli bir sütundan (NAME) ibarətdir, lakin ümumilikdə bir neçə sütundan ibarət ola bilər; o, həmçinin hesablanmış dəyərləri və ya sabitləri ehtiva edə bilər. Bu variantların hər birinə nümunələr verəcəyik. Yaranan cədvəldə birdən çox sütun olmalıdırsa, bütün tələb olunan sütunlar sonra siyahıya alınır SELECT əmrləri vergüllə ayrılır. Məsələn, SELECT WORKER_ID, NAME ifadəsi WORKER_ID və NAME sütunlarından ibarət cədvəllə nəticələnəcək.

SELECT bəndi. Nəticə cədvəlinin sütunlarını təyin edir.

From. FROM bəndi sorğu ilə daxil olan bir və ya bir neçə cədvəli müəyyən edir. SELECT və WHERE bəndlərində sadalanan bütün sütunlar FROM əmrində sadalanan cədvəllərdən birində mövcud olmalıdır. SQL2-də bu cədvəllər birbaşa sxemdə əsas cədvəllər və ya məlumat görünüşü kimi müəyyən edilə bilər və ya onlar SQL sorğuları nəticəsində yaranan adsız cədvəllər ola bilər. Sonuncu halda sorğu FROM əmrində açıq şəkildə verilir.

FROM ifadəsi. Sorğunun əldə etdiyi mövcud cədvəlləri təyin edir.

Harada. WHERE bəndində şərt var. bunun əsasında cədvəl(lər)in sətirləri seçilir. Bizim nümunəmizdə şərt ondan ibarətdir ki, SKILL_TYPE sütununda həmişə SQL-də mətn sabitləri ilə edildiyi kimi, apostroflarla əhatə olunmuş "Plasterer" sabiti olmalıdır. WHERE bəndi ən dəyişkən SQL əmridir; çox müxtəlif şərtləri ehtiva edə bilər. Müzakirəmizin çox hissəsi WHERE əmrində icazə verilən müxtəlif konstruksiyaların təsvirinə həsr olunacaq.

WHERE bəndi. Göstərilən cədvəllərdən hansı sətirlərin seçildiyinə əsaslanaraq şərti müəyyənləşdirir.

Yuxarıdakı SQL sorğusu sistem tərəfindən aşağıdakı ardıcıllıqla işlənir: FROM, WHERE, SELECT. Yəni, FROM əmrində göstərilən cədvəlin sətirləri emal üçün iş sahəsinə yerləşdirilir. Sonra WHERE bəndi ardıcıllıqla hər sıraya tətbiq edilir. WHERE şərtini təmin etməyən bütün sətirlər nəzərdən keçirilmir. Sonra WHERE şərtini ödəyən sətirlər SELECT ifadəsi ilə işlənir. Nümunəmizdə hər bir belə sətirdən NAME seçilir və bütün seçilmiş dəyərlər sorğunun nəticələri kimi çıxarılır.

Sorğu: Ofis binaları haqqında bütün məlumatları təqdim edin.

HARADA TİP = "Ofis"

Nəticə:

BLDG IDADRESSTYPEQLTY SƏVİYYƏSİ

312 Elm küç., 123 Ofis 2 2

210 Berezovaya küç. 1011 Office Z 1

111 Osinovaya küç. 1213 Office 4 1

SELECT əmrindəki ulduz işarəsi (*) “bütün sıra” deməkdir. Bu, tez-tez istifadə edəcəyimiz rahat stenoqrafiyadır.

Sorğu: Hər bir elektrikçinin həftəlik maaşı nə qədərdir?

ADI SEÇİN, "Həftəlik maaş = ", 40 * HRLY_RATE

WHERE SKILL_TYPE = "Elektrikçi"

Nəticə:

M. Faraday Həftəlik maaş = 500.00

H.Columbus Həftəlik maaş = 620.00

Bu sorğu həm simvol sabitlərinin (bizim nümunəmizdə "Həftəlik maaş = "), həm də SELECT əmrindəki hesablamaların istifadəsini təsvir edir. SELECT ifadəsi daxilində siz rəqəmli sütunlardan və rəqəmsal sabitlərdən, həmçinin standart hesab operatorlarından ( +, -, *, /), mötərizədən istifadə etməklə lazımi qruplaşdırılır. Yenisini də daxil etdik SİFARİŞ əmri Sorğu nəticəsini göstərilən sütun üzrə artan alfasayısal sıra ilə çeşidləyən BY. Nəticələri azalan ardıcıllıqla çeşidləmək istəyirsinizsə, əmrə DESC əlavə etməlisiniz. ORDER BY bəndi nəticələri bir neçə sütun üzrə sıralaya bilər, bəziləri artan, digərləri isə azalan qaydada. Sıralamanın əsas açar sütunu əvvəlcə siyahıya salınır.

Xarakter sabiti. Hərflərdən, rəqəmlərdən və “xüsusi” simvollardan ibarət sabit.

Sorğu: Kimin saatlıq tarifi 10 dollardan 12 dollara qədərdir?

HRLY_RATE > = 10 VƏ HRLY_RATE< - 12

Nəticə:

İşçi ID NAME HRLY_RATE SKILL_TYPE SUPV_ID

Bu sorğu WHERE ifadəsinin bəzi əlavə xüsusiyyətlərini təsvir edir: müqayisə operatorları və Boolean AND operatoru. Altı müqayisə operatoru (=,<>(bərabər deyil),<, >, <=, >=). Boolean operatorları AND, OR, və NOT mürəkkəb şərtlər yaratmaq və ya şərti inkar etmək üçün istifadə edilə bilər. Proqramlaşdırma dillərində olduğu kimi, mötərizələrdən şərtləri qruplaşdırmaq üçün istifadə edilə bilər.

Müqayisə operatorları =,<>, <, >, <=, >=.

Boolean əməliyyatları VƏ (VƏ), OR (VEYA) və DEYİL (HE) .

Bu sorğunu tərtib etmək üçün BETWEEN (arasında) operatorundan da istifadə edə bilərsiniz:

HRLY_RATE 10 ilə 12 ARASINDA

BETWEEN kəmiyyəti birincisi ikincidən kiçik olan digər iki kəmiyyətlə müqayisə etmək üçün istifadə edilə bilər, əgər müqayisə edilən kəmiyyət bu kəmiyyətlərin hər birinə və ya onların arasında olan hər hansı dəyərə bərabər ola bilər.

Müraciət: Suvaqçıları, dam ustalarını və elektrikçiləri siyahıya alın.

HARƏDƏ BACARIQ_TİPİ ("Sıvaqçı", "Dam ustası", "Elektrikçi")

Nəticə:

WORKER_ID ADI HRLY_RATE SKILL_TYPE SUPV_ID

1412 K.Nemo 13.75 Suvaqçı 1520

2920 R. Qarret 10.00 Dam ustası 2920

1520 G. Rickover 11.75 Suvaqçı 1520

Bu sorğu IN (B) müqayisə operatorunun istifadəsini izah edir. Əgər cərgənin ixtisas növü mötərizədə göstərilən dəstənin daxilində yerləşirsə, yəni ixtisas növü suvaqçı, dam ustası və ya elektrikçidirsə, HARADA şərti doğru hesab olunur. Biz alt sorğularda yenidən IN operatorunu görəcəyik.

Fərz edək ki, ixtisasımızın yazılışını dəqiq xatırlaya bilmirik: “elektrik” və ya “elektronik mühəndis” və ya başqa bir şey. Müəyyən edilməmiş simvol sətirlərini əvəz edən joker simvollar sorğuda qeyri-dəqiq yazıları tapmağı asanlaşdırır.

Nümunə simvolları. Müəyyən edilməmiş simvol sətirlərini əvəz edən simvollar.

Sorğu:İxtisas növü “Elək” ilə başlayan işçiləri sadalayın.

BACARIQ_TYPE BƏYƏNİLƏN HARƏDƏ ("Seç%")

Nəticə:

İŞÇİ ID-si ADI HRLY_RATE SKILL_TYPE SUPV_ID

1235 M. Faraday 12.50 Elektrik 1311

1311 H. Kolumb 15.50 Elektrik 1311

SQL-də iki joker simvol var: % (faiz) və _ (alt xətt). Alt xətt dəqiq bir qeyri-müəyyən simvolu əvəz edir. Faiz sıfırdan başlayaraq ixtiyari sayda simvolu əvəz edir. Joker simvollardan istifadə edildikdə, simvol dəyişənlərini sabitlərlə müqayisə etmək üçün LIKE operatoru tələb olunur. Digər nümunələr:

ADI "__Columbus" kimi

ADI "__K%" BƏYƏNİN

Əgər NAME iki simvoldan sonra "Kolumb"dan ibarətdirsə, birinci misaldakı şərt doğrudur. WORKER cədvəlində bütün adlar birinci başlanğıc və nöqtə ilə başlayır. Beləliklə, bu şərtdən istifadə edərək biz. "Kolumb" soyadlı bütün işçiləri tapaq. İkinci nümunənin şərti soyadları “K” hərfi ilə başlayan bütün işçiləri tapmağa imkan verir.

Sorğu: Növbəti iki həftə ərzində başlayan bütün işləri tapın.

START_DATE CURRENT_DATE ARASINDA HARADA

Nəticə:(Cari tarixin CARİ TARİX = 10.10 olduğunu fərz edin)

WORKER_ID BLDG_ID START_DATE NUM_DAYS

1235 312 10.10 5

1235 515 17.10 22

3231 111 10.10 8

1412 435 15.10 15

3231 312 24.10 20

1311 460 23.10 24

Bu sorğu tarix və interval qiymətləri ilə BETWEEN operatorunun istifadəsini göstərir. CURRENT_DATE həmişə bu günün tarixini qaytaran funksiyadır. İfadə

CURRENT_DATE + INTERVAL "14" GÜN

cari tarixə iki həftəlik müddət əlavə edir. Beləliklə, START_DATE sütununun dəyəri 10/10 və 10/24 arasında olarsa, TƏTBİQ seçilir (bu günün 10/10 olduğunu nəzərə alaraq). Buradan görə bilərik ki, tarix sahələrinə interval dəyərləri əlavə edə bilərik. Üstəlik, intervalların dəyərlərini tam ədədlərlə çarpa bilərik. Məsələn, fərz edək ki, biz müəyyən həftələrdə hansı rəqəmin olacağını öyrənmək istəyirik (NUM_WEEKS dəyişəni ilə işarələnir). Bunu belə edə bilərik:

CURRENT_DATE + INTERVAL "7" GÜN * NUM_WEEKS

2. Çox cədvəlli sorğular

Məlumat elementlərini vahid cədvəlin sərhədləri boyunca əlaqələndirmək bacarığı istənilən verilənlər bazası dili üçün vacibdir. Əlaqəli cəbrdə bu funksiya birləşmə əməliyyatı ilə yerinə yetirilir. Baxmayaraq ki, SQL-in çox hissəsi bilavasitə relyasiya hesablamalarına əsaslanır, SQL müxtəlif cədvəllərdən verilənləri əlaqəli cəbrin birləşmə əməliyyatına oxşar şəkildə əlaqələndirir. İndi bunun necə edildiyini göstərəcəyik. Müraciəti nəzərdən keçirin:

Sorğu:

Cavab üçün lazım olan məlumatlar iki cədvəldədir: İŞÇİ və TƏKLİF. SQL həlli hər iki cədvəli FROM əmrində siyahıya salmağı və WHERE bəndinin xüsusi növünü təyin etməyi tələb edir:

SKILL_TYPE SEÇİN

İŞÇİDƏN, TƏKLİF

HARADA İŞÇİ.İŞÇİ_ID = TƏKLİF.İŞÇİ_ID

VƏ BLDG_ID = 435

Burda nə baş verir? Sistemin bu sorğunu necə emal etməsində iki mərhələni nəzərdən keçirməliyik.

1. Həmişə olduğu kimi əvvəlcə FROM bəndi işlənir. Lakin bu halda komanda iki cədvəli təyin etdiyi üçün sistem bu cədvəllərin sətirlərinin dekart hasilini yaradır. Bu o deməkdir ki, hər iki cədvəlin sütunlarından ibarət (məntiqi olaraq) bir böyük cədvəl yaradılır, bir cədvəlin hər sətri digər cədvəlin hər sətri ilə qoşalaşır. Bizim nümunəmizdə WORKER cədvəlində beş sütun, TƏTBİQ cədvəlində isə dörd sütun olduğu üçün FROM əmri ilə istehsal olunan Dekart hasilinin doqquz sütunu olacaq. Dekart məhsulunun cərgələrinin ümumi sayı m * n-ə bərabərdir, burada m İŞÇİ cədvəlinin sətirlərinin sayıdır; n isə TƏSHİFƏ cədvəlindəki sətirlərin sayıdır. WORKER cədvəlində 7, TƏTBİQ cədvəlində isə 19 sıra olduğundan, Dekart hasilində 7x19 və ya 133 sətir olacaq. FROM əmri ikidən çox cədvəli sadalayırsa, komandada göstərilən bütün cədvəllərin Kartezian hasilatı yaradılır.

Kartezyen məhsul. Bir cədvəlin hər cərgəsinin birləşdirilməsinin nəticəsi hər biri başqa bir cədvəldən bir sıra.

2. Nəhəng relyasiya cədvəlini yaratdıqdan sonra sistem əvvəlki kimi WHERE əmrindən istifadə edir. Cədvəlin hər sətri FROM əmri ilə yaradılmışdır. WHERE şərtinin təmin olunub-olunmadığını yoxlamaq üçün yoxlanılır. Şərti təmin etməyən cərgələr baxılmaqdan çıxarılır. Sonra SEÇ bəndi qalan sətirlərə tətbiq edilir.

Sorğumuzdakı WHERE bəndində iki şərt var:

1. İŞÇİ. WORKER_ID = ASIGNMENT.WORKER_ID

2. BLDG_ID = 435

Bu şərtlərdən birincisi birləşmə şərtidir. Nəzərə alın ki, həm WORKER, həm də ASSIGNMENT cədvəllərində WORKER_ID adlı sütun olduğundan, onların Dekart məhsulu bu adda iki sütundan ibarət olacaq. Bunları fərqləndirmək üçün sütun adından əvvəl nöqtə ilə ayrılmış mənbə cədvəlinin adını çəkirik.

Birinci şərt o deməkdir ki, seçilmiş hər hansı sətirdə WORKER cədvəlindən WORKER_ID sütununun dəyəri ASSIGNMENT cədvəlindəki WORKER_ID sütununun dəyərinə uyğun olmalıdır. Reallıqda biz WORKER_ID ilə iki cədvələ qoşuluruq. Bu iki sütunun dəyərləri bərabər olmayan bütün sətirlər məhsul cədvəlindən xaric edilir. Relational cəbrin təbii birləşmə əməliyyatını yerinə yetirərkən də eyni şey baş verir. (Lakin təbii birləşmədən hələ də müəyyən fərq var: SQL əlavə WORKER_ID sütununu avtomatik silmir). Bu iki cədvəlin BLDG_ID = 435 əlavə şərti ilə tam birləşməsi Şəkildə göstərilmişdir. 1. SELECT əmrindən istifadə son nəticədə aşağıdakı sorğu nəticəsini verəcək:

BACARIQ NÖVÜ

suvaqçı

Dam ustası

Elektrikçi

düyü. 1. İŞÇİ və TAPŞIŞ cədvəllərinə qoşulma

İndi biz SQL-də cədvəlin özünə necə qoşulacağını göstərəcəyik.

Sorğu: Menecerlərinin adlarını göstərməklə işçilərin siyahısını yazın.

A.WORKER_NAME, B.WORKER_NAME SEÇİN

İŞÇİ A-DAN, İŞÇİ B

B.WORKER_ID = A.SUPV_ID

Bu nümunədəki FROM bəndi WORKER cədvəlinin iki "nüsxəsini" yaradır və onlara A və B ləqəblərini verir. Təxəllüsü cədvələ verilən alternativ addır. Sonra WORKER cədvəlinin A və B nüsxələri B-də WORKER_ID və A-da SUPV_ID bərabərlik şərtinə əsaslanan WHERE əmri ilə birləşdirilir. Beləliklə, A-dan hər bir sətir A sətirinin meneceri haqqında məlumatı ehtiva edən B cərgəsinə birləşdirilir. (Şəkil 2).

düyü. 2. WORKER cədvəlinin iki nüsxəsinin birləşdirilməsi

Hər sətirdən iki işçi adını seçməklə biz tələb olunan siyahını alırıq:

A.NAMEB.NAME

M. Faraday H. Kolumb

K.Nemo G.Rikover R.Qarret R.Qarret

P. Meyson P. Meyson G. Rikver Q. Rikver H. Kolumb H. Kolumb C. Vəkil P. Meyson

Ləqəb. Cədvələ verilən alternativ ad.

A.WORKER_NAME işçini, B.WORKER_NAME isə meneceri təmsil edir. Nəzərə alın ki, bəzi işçilər öz menecerləridir, bu da onların sətirlərində WORKER_ID - SUPV_ID bərabərliyindən irəli gəlir.

SQL-də eyni anda ikidən çox cədvəli əlaqələndirə bilərsiniz:

Sorğu

İŞÇİ_NAME SEÇİN

İŞÇİDƏN, TƏQDİMATDAN, BİNADAN

WHERE WORKER.WORKER_ID = ASIGNMENT.WORKER_ID AND ASSIGNMENT.BLDG_ID = BİNA.BLDG_ID VƏ

TİP = "Ofis"

Nəticə:

M. Faraday

G.Rikover

J.Vəkil

Nəzərə alın ki, əgər sütun adı (məsələn, WORKER_ID və ya BLDG_ID) birdən çox cədvəldə görünürsə, qeyri-müəyyənliyin qarşısını almaq üçün sütun adını orijinal cədvəlin adı ilə üst-üstə qoymalıyıq. Amma əgər sütun adı bizim nümunəmizdəki TYPE kimi yalnız bir cədvəldə baş verirsə, onda heç bir qeyri-müəyyənlik yoxdur, ona görə də cədvəl adının göstərilməsinə ehtiyac yoxdur.

Bu sorğudakı SQL əmrləri üç əlaqəli verilənlər bazası cədvəlindən bir cədvəl yaradır. İlk iki cədvəl WORKER_ID ilə birləşdirilir, bundan sonra üçüncü cədvəl BLDG_ID ilə nəticələnmiş cədvələ birləşdirilir. Vəziyyət

TİP = "Ofis"

WHERE bəndi ofis binaları istisna olmaqla, bütün sətirlərin xaric edilməsinə səbəb olur. Bu, sorğunun tələblərinə cavab verir.

3. Alt sorğular

Alt sorğu. Sorğu daxilində sorğu

Alt sorğu sorğunun WHERE bəndində yerləşdirilə bilər və bununla da WHERE bəndinin imkanları genişləndirilə bilər. Bir nümunəyə baxaq.

Sorğu: 435 saylı binaya təyin olunan fəhlələrin ixtisasları hansılardır?

SKTLL_TYPE SEÇİN

İŞÇİ_İDDİYASI OLAN İŞÇİDƏN

(İŞÇİ_ID. SEÇİN

BLDG_ID HARADA = 435)

Bu nümunədə alt sorğu

(İŞÇİ_ID. SEÇİN

BLDG_ID HARADA = 435)

İçərisində alt sorğu olan sorğu çağırılır xarici sorğu və ya əsas tələb. Alt sorğu aşağıdakı işçi şəxsiyyət vəsiqələrinin yaradılması ilə nəticələnir:

İşçi ID

Xarici sorğu. Bütün alt sorğuları ehtiva edən əsas sorğu.

Bu identifikatorlar dəsti daha sonra xarici sorğuda alt sorğunun yerini tutur. Bu andan etibarən xarici sorğu alt sorğunun yaratdığı çoxluqdan istifadə etməklə yerinə yetirilir. Xarici sorğu WHERE bəndinə uyğun olaraq WORKER cədvəlinin hər bir sırasını emal edir. Əgər sətrin WORKER_ID-i alt sorğu tərəfindən yaradılmış (IN) dəstində yerləşirsə, o zaman cərgənin SKILL_TYPE-i seçilir və nəticədəki cədvəldə göstərilir:

BACARIQ NÖVÜ

suvaqçı

Dam ustası

Elektrikçi

Alt sorğunun SELECT bəndində WORKER_ID və yalnız WORKER_ID olması çox vacibdir. Əks halda, WORKER_ID-nin işçi identifikatorları dəstində olması mənasını verən xarici sorğunun WHERE bəndinin heç bir mənası olmayacaq.

Nəzərə alın ki, alt sorğu ən azı bir sıra əsas sorğu tərəfindən nəzərdən keçirilməzdən əvvəl məntiqi olaraq icra edilə bilər. Müəyyən mənada alt sorğu əsas sorğudan müstəqildir. Tam sorğu kimi icra oluna bilər. Biz deyirik ki, belə bir alt sorğu əsas sorğu ilə əlaqəli deyil. Bir azdan görəcəyimiz kimi, alt sorğular əlaqələndirilə bilər.

Əlaqəsiz alt sorğu. Dəyəri hər hansı xarici sorğudan asılı olmayan alt sorğu.

Budur, alt sorğu daxilindəki alt sorğunun nümunəsi.

Sorğu: Ofis binalarına təyin edilmiş işçilərin siyahısını verin.

Yenidən əlaqəni araşdırdığımız sorğuya baxırıq.

İŞÇİ_MAME SEÇİN

İŞÇİ_İDDİYASI HARADA

(İŞÇİ_ID. SEÇİN

BLDG_ID HARADA

NÖVÜ = "Ofis"))

Nəticə:

M. Faraday

G.Rikover

J.Vəkil

Nəzərə alın ki, sütun adlarını heç bir yerdə cədvəl adları ilə prefiks etməyə ehtiyac yoxdur, çünki hər bir alt sorğu bir və yalnız bir cədvəli emal edir, ona görə də heç bir qeyri-müəyyənlik yarana bilməz.

Sorğunun icrası daxili-xarici qaydada baş verir. Yəni əvvəlcə ən daxili sorğu (və ya "ən aşağı"), sonra onu ehtiva edən alt sorğu, sonra isə xarici sorğu yerinə yetirilir.

Əlaqəli alt sorğular. Yuxarıda müzakirə edilən bütün alt sorğular istifadə olunduğu əsas sorğulardan müstəqil idi. Müstəqil dedikdə, alt sorğuların tam sorğular kimi öz-özünə icra oluna biləcəyini nəzərdə tuturuq. İndi icra nəticələri əsas sorğunun nəzərdən keçirdiyi sıradan asılı ola bilən alt sorğular sinfini nəzərdən keçirməyə davam edirik. Belə alt sorğular korrelyasiya edilmiş alt sorğular adlanır.

Əlaqəli alt sorğu. Nəticəsi əsas sorğunun nəzərdən keçirdiyi sıradan asılı olan alt sorğu.

Sorğu: Saatlıq tarifləri menecerlərininkindən yüksək olan işçiləri sadalayın.

İŞÇİ_NAME SEÇİN

HARADA A.HRLY_RATE >

(B.HRLY_RATE SEÇİN

B.WORKER_ID = A.SUPV_ID)

Nəticə:

Bu sorğunun yerinə yetirilməsi üçün məntiqi addımlar:

1. Sistem İŞÇİ cədvəlinin iki nüsxəsini yaradır: A nüsxəsi və B surəti. Onları müəyyən etdiyimiz üsula görə, A işçiyə, B menecerə aiddir.

2. Sonra sistem hər bir A sətirini nəzərdən keçirir. Verilmiş cərgə WHERE şərtini ödədiyi halda seçilir. Bu şərt o deməkdir ki, əgər onun HRLY_RATE dəyəri alt sorğu tərəfindən yaradılan HRLY_RATE dəyərindən böyükdürsə, sıra seçiləcək.

3. Alt sorğu WORKER_ID-si A sətirinin SUPV_ID-inə bərabər olan B sətirindən HRLY_RATE dəyərini seçir. Bu anəsas tələblə nəzərdən keçirilir. Bu menecerin HRLY_RATE qiymətidir.

Nəzərə alın ki, A.HRLY_RATE yalnız bir dəyərlə müqayisə oluna bildiyi üçün alt sorğu yalnız bir dəyər qaytarmalıdır. Bu dəyər hansı A sətirinin nəzərdən keçirildiyindən asılı olaraq dəyişir. Beləliklə, alt sorğu əsas sorğu ilə əlaqələndirilir. Daha sonra daxili funksiyaları öyrəndiyimiz zaman korrelyasiya edilmiş alt sorğuların daha çox nümunələrini görəcəyik.

EXISTS və EXISTS operatorları

Tutaq ki, müəyyən bir binada işləmək üçün təyin olunmayan işçiləri müəyyən etmək istəyirik. Zahirən görünür ki, belə bir tələbi, sadəcə olaraq, sorğunun müsbət variantını inkar etməklə asanlıqla təmin etmək olar. Tutaq ki, məsələn, BLDG_ID 435 olan bina ilə maraqlanırıq. Sorğunu nəzərdən keçirin:

WORKER_ID SEÇİN

BLDG_ID 435 DEYİL

Təəssüf ki, bu, həllin səhv formalaşdırılmasıdır. Müraciət bizə sadəcə olaraq başqa binalarda işləyən işçilərin şəxsiyyət vəsiqələrini verəcək. Aydındır ki, onlardan bəzilərini 435 saylı binaya da aid etmək olar.

Düzgün tərtib edilmiş həll NOT EXISTS operatorundan istifadə edir:

WORKER_ID SEÇİN

MÖVCUD OLMAYAN YERDE

HARADA TƏQDİM.İŞÇİ_ID = İŞÇİ.İŞÇİ_ID VƏ

Nəticə:

WORKER_ID

EXISTS və NOT EXISTS operatorları həmişə alt sorğudan əvvəl yerləşdirilir. Alt sorğunun yaratdığı çoxluq boş deyilsə, EXISTS doğru olaraq qiymətləndirilir. Əgər alt sorğu tərəfindən yaradılan çoxluq boşdursa, MÖVCUD "yanlış" dəyərini alır. NOT EXISTS operatoru, əlbəttə ki, tam əksini işləyir. Alt sorğunun nəticəsi boş olarsa doğrudur, əks halda yanlışdır.

EXISTS operatoru. Nəticə dəsti boş deyilsə, doğru qaytarır.

operatoru YOXDUR. Nəticə dəsti boş olarsa, doğru qaytarır.

Bu nümunədə biz NOT EXISTS operatorundan istifadə etdik. Alt sorğu, WORKER_ID-nin əsas sorğu tərəfindən nəzərdən keçirilən cərgə ilə eyni dəyərə malik olduğu və BLDG_ID-nin 435-ə bərabər olduğu ASIGNMENT cədvəlinin bütün sətirlərini seçir. Bu dəst boşdursa, əsas sorğu tərəfindən nəzərdən keçirilən işçi sırası belədir. seçilmişdir, çünki bu o deməkdir ki, Bu işçi 435 saylı binada işləmir.

Təqdim etdiyimiz həlldə biz əlaqəli alt sorğudan istifadə etdik. NOT EXISTS əvəzinə IN operatorundan istifadə etsək, əlaqəsi olmayan alt sorğu ilə əldə edə bilərik:

WORKER_ID SEÇİN

İŞÇİNİN_İDDƏNİ OLMAYAN YERDƏ

(İŞÇİ_ID. SEÇİN

BLDG_ID = 435)

Bu həll NOT EXISTS operatoru ilə həlldən daha sadədir. Təbii sual yaranır: niyə bizə MÖVCUDLAR lazımdır və ümumiyyətlə MÖVCUDLAR? Cavab odur ki, MÖVCUD OLMAZ şərtdə "hər biri" sözünü ehtiva edən sorğuları həll etməyin yeganə yoludur. Belə sorğular bölgü əməliyyatından istifadə etməklə relyasiya cəbrində, universal kəmiyyət göstəricisindən istifadə etməklə relyasiya hesablamasında həll edilir. Şərtində “hər” sözü olan sorğu nümunəsi:

Sorğu: Hər bir binaya təyin edilmiş işçilərin siyahısını qeyd edin.

Bu sual SQL-də ikiqat inkarlardan istifadə etməklə həyata keçirilə bilər. Sorğunu ikiqat mənfi daxil etmək üçün yenidən tərtib edəcəyik:

Sorğu: Kimin üçün belə işçiləri sadalayın yox onların təyin olunmadığı bir bina var.

Biz ikiqat neqativi vurğuladıq. Aydındır ki, bu sorğu məntiqi olaraq əvvəlki ilə bərabərdir.

İndi biz həlli SQL-də formalaşdırmaq istəyirik. Son həllin başa düşülməsini asanlaşdırmaq üçün ilk növbədə ilkin problemin həllini veririk: hipotetik işçinin "1234" olduğu bütün binaların müəyyən edilməsi problemi. yox təyin edilmişdir.

(I) BLDG_ID SEÇİN

MÖVCUD OLMAYAN YERDE

TƏKLİF.İŞÇİ_ID = 1234)

Biz bu sorğunu (I) qeyd etdik, çünki daha sonra ona istinad edəcəyik. Əgər bu tələbi təmin edən bina yoxdursa, o zaman hər bir binaya 1234 saylı işçi təyin edilir və buna görə də ilkin tələbin şərtlərini təmin edir. Orijinal sorğunun həllini əldə etmək üçün biz sorğunu (I) xüsusi işçi 1234-dən WORKER_ID dəyişəninə ümumiləşdirməli və bu dəyişdirilmiş sorğunu daha böyük sorğunun alt sorğusuna çevirməliyik. Həll yolu budur:

(II) İŞÇİ_ID SEÇİN

MÖVCUD OLMAYAN YERDE

MÖVCUD OLMAYAN YERDE

HARADA ASIGNMENT.BLDG_ID = BUILDING.BLDG_ID VƏ

ASIGNMENT.WORKER_ID = WORKER.WORKER_ID)

Nəticə:

İşçi ID

Qeyd edək ki, sorğunun (II) dördüncü sətirindən başlayan alt sorğu (I) sorğu ilə eynidir və "1234" WORKER.WORKER_ID ilə əvəz edilmişdir. Sorğu (II) aşağıdakı kimi oxuna bilər:

WORKER_ID-nin təyin edilmədiyi bina yoxdursa, WORKER-dən WORKER_ID seçin.

Bu, ilkin sorğunun şərtlərinə uyğun gəlir.

Görürük ki, NOT EXISTS operatoru relyasiya cəbrində bölmə əməliyyatı tələb edən sorğuları və relational hesablamada universal kəmiyyət göstəricisini formalaşdırmaq üçün istifadə edilə bilər. İstifadə asanlığı baxımından NOT EXISTS operatoru heç bir xüsusi fayda təklif etmir, yəni iki dəfə MÖVCUD OLMAYAN SQL sorğularını başa düşmək bölmə ilə əlaqəli cəbr həllərindən və ya universal kəmiyyət göstəriciləri ilə əlaqəli hesablama həllərindən asan deyil. Bu cür sorğuların daha təbii şəkildə həll edilməsinə imkan verən dil konstruksiyaları yaratmaq üçün daha çox araşdırma tələb olunacaq.

Quraşdırılmış funksiyalar

Bu tip sualları nəzərdən keçirək:

Maksimum və minimum saatlıq tariflər hansılardır? 435 saylı binada işçilərin orta hesabla neçə gün işləməsi var? 312 saylı binada suvaq işlərinə cəmi neçə gün ayrılıb? Neçə fərqli ixtisas var?

Bu suallara cavab vermək üçün cədvəldə bir çox sətirə baxan və tək qiymət qaytaran statistik funksiyalar tələb olunur. SQL-də daxili funksiyalar və ya dəst funksiyaları adlanan beş belə funksiya var. Bu funksiyalar SUM (cəm), AVG (orta), COUNT (miqdar), MAX (maksimum) və MIN (minimum) funksiyalarıdır.

Daxili funksiya (set funksiyası). Çox sətirdə işləyən statistik funksiya: SUM (cəm), AVG (orta), COUNT (kəmiyyət), MAX (maksimum), MIN (minimum).

Sorğu: Maksimum və minimum saatlıq tariflər hansılardır?

MAX SEÇİN(HRLY_RATE), MIN(HRLY_RATE)

Nəticə: 17.40, 8.20

MAX funksiyaları və MIN bir cədvəl sütununda işləyir. Bu sütundan müvafiq olaraq maksimum və ya minimum dəyəri seçirlər. Sorğumuzun tərtibində WHERE bəndi yoxdur. Növbəti nümunəmizdən göründüyü kimi əksər sorğular üçün bu belə olmaya bilər.

Sorğu: 435 saylı binada işçilərin orta hesabla neçə gün işləməsi var?

AVG SEÇİN(NUM_DAYS)

BLDG_ID =435

Nəticə: 12.33

Sorğu: 312 saylı binada suvaq işlərinə cəmi neçə gün ayrılıb?

CƏMİ SEÇİN(NUM_DAYS)

TƏKLİFDƏN, İŞÇİ

HARADA İŞÇİ.İŞÇİ_İDDİYASI = TƏKLİF.İŞÇİ_ID VƏ

SKILL_TYPE = "Sıvaqçı" VƏ

Nəticə: 27

Həll ASSIGNMENT və WORKER cədvəlləri arasında birləşmədən istifadə edir. Bu lazımdır, çünki SKILL_TYPE WORKER cədvəlində, BLDG_ID isə ASSIGNMENT cədvəlindədir.

Sorğu: Neçə fərqli ixtisas var?

SAYI SEÇİN (FƏRQLİ SKILL_TYPE)

Nəticə: 4

Eyni ixtisas bir neçə fərqli cərgədə görünə biləcəyi üçün sistemin eyni ixtisas növünü birdən çox saymasının qarşısını almaq üçün bu sorğuda DISTINCT açar sözündən istifadə etməlisiniz. DISTINCT operatoru daxili funksiyaların hər hansı biri ilə istifadə oluna bilər, baxmayaraq ki, əlbəttə ki, MAX və MIN funksiyaları ilə lazımsızdır.

FƏRQLİ. Dublikat xətləri aradan qaldıran operator.

SUM və AVG funksiyaları yalnız rəqəmli sütunlarla istifadə edilməlidir. Digər funksiyalar həm rəqəm, həm də simvol məlumatları ilə istifadə edilə bilər. COUNT-dan başqa bütün funksiyalar hesablanmış ifadələrlə istifadə edilə bilər. Misal üçün:

Sorğu: Orta həftəlik əmək haqqı nə qədərdir?

AVG SEÇİN (40 * HRLY_RATE)

Nəticə: 509.14

COUNT fərdi sütuna deyil, bütün sıraya istinad edə bilər :

Sorğu: Neçə binada keyfiyyət səviyyəsi 3 var?

SAYI SEÇİN (*)

BİNADAN HARADA

Nəticə: 3

Bütün bu nümunələrdən göründüyü kimi, əgər SELECT əmri daxili funksiyadan ibarətdirsə, o zaman həmin SELECT əmrində başqa heç nə görünə bilməz. Bu qaydanın yeganə istisnası indi nəzərdən keçirəcəyimiz GROUP BY bəndidir.

GROUP BY və HAVING bəndləri

İdarəetmədə bir çox qruplarda hər bir qrup haqqında statistik məlumatlar tez-tez tələb olunur. Məsələn, aşağıdakı sorğunu nəzərdən keçirin:

Sorğu: Hər bir menecer üçün tabeliyində olanlar arasında maksimum saatlıq tarifi tapın.

Bu problemi həll etmək üçün işçiləri rəhbərlərinə görə qruplara ayırmalıyıq. Bundan sonra hər qrup daxilində maksimum təklifi müəyyən edəcəyik. SQL-də bu belə edilir:

SUPV_ID İYİ QRUPLA

Nəticə:

SUPV_IDMAX(HRLY RATE)

Bu sorğunu emal edərkən sistem əvvəlcə aşağıdakı qaydadan istifadə edərək WORKER cədvəlinin sətirlərini qruplara bölür. Sətirlər eyni SUPV_ID-ə malik olduqda eyni qrupa yerləşdirilir. Sonra hər qrupa SELECT bəndi tətbiq edilir. Bu qrupda yalnız bir SUPV_ID dəyəri olduğundan, qrupda SUPV_ID qeyri-müəyyənliyi yoxdur. Hər qrup üçün SELECT bəndi SUPV_ID-ni verir və həmçinin MAX(HRLY_RATE) dəyərini hesablayır və çıxarır. Nəticə yuxarıda təqdim olunur.

Daxili funksiyaları olan SELECT əmrində yalnız GROUP BY bəndinə daxil olan sütunlar görünə bilər. Qeyd edək ki, SUPV_ID SELECT əmrində istifadə oluna bilər, çünki o, GROUP BY bəndinə daxil edilmişdir.

GROUP BY bəndi. Satırların göstərilən sütun(lar)ın ümumi dəyərləri ilə qruplara bölünməsi lazım olduğunu göstərir.

GROUP BY bəndi müəyyən mürəkkəb hesablamalar aparmağa imkan verir. Məsələn, biz bu maksimum təkliflərin orta qiymətini öyrənmək istəyə bilərik. Bununla belə, daxili funksiyalarla hesablama o mənada məhduddur ki, o, daxili funksiyaların digər daxili funksiyaların içərisində istifadəsinə imkan vermir. Belə bir ifadə kimi

AVG(MAX(HRLY_RATE))

qadağandır. Belə bir müraciətin icrası iki mərhələdən ibarət olacaq. Əvvəlcə maksimum təklifləri yeni cədvələ qoymalıyıq, ikinci mərhələdə isə onların orta qiymətini hesablamalıyıq.

GROUP BY əmri ilə WHERE bəndindən istifadə edə bilərsiniz:

Sorğu: Hər bir bina növü üçün tapın orta səviyyə statuslu binalar arasında keyfiyyət 1.

TİP SEÇİN, AVG(QLTY_LEVEL)

STATUS = 1

Nəticə:

TYPEAVG(QLTY_LEVEL)

Mağaza 1

Yaşayış binası 3

WHERE bəndi GROUP BY ifadəsindən əvvəl yerinə yetirilir. Beləliklə, heç bir qrup 1-dən başqa statusu olan cərgəni ehtiva edə bilməz. 1-ci status sətirləri TYPE dəyərinə görə qruplaşdırılır və sonra hər qrupa SELECT bəndi tətbiq edilir.

HAVING ifadəsi. Şərtləri qruplara qoyur.

GROUP BY bəndinin yaratdığı qruplara şərtləri də tətbiq edə bilərik. Bu HAVING ifadəsindən istifadə etməklə edilir. Məsələn, tutaq ki, əvvəlki sorğulardan birini daha konkretləşdirmək qərarına gəldik:

Sorğu: Birdən çox tabeliyində olan hər bir menecer üçün onun tabeliyində olanlar arasında maksimum saatlıq tarifi tapın.

Bu şərti müvafiq HAVING əmri ilə əks etdirə bilərik:

SEÇİN SUPV_ID, MAX(HRLY_RATE)

SUPV_ID İLƏ İŞÇİ QRUPDAN

SAYI (*) > 1

Nəticə:

SUPV_ID MAX(HRLY_RATE)

WHERE və HAVING bəndləri arasındakı fərq ondan ibarətdir ki, WHERE sətirlərə, HAVING isə qruplara aiddir.

Sorğu həm WHERE, həm də HAVING bəndini ehtiva edə bilər. Bu halda WHERE bəndi qruplaşmadan əvvəl yerinə yetirildiyi üçün əvvəlcə yerinə yetirilir. Məsələn, əvvəlki sorğunun aşağıdakı modifikasiyasını nəzərdən keçirin:

Sorğu: Hər bir bina növü üçün status 1 olan binalar arasında keyfiyyətin orta səviyyəsini tapın. Yalnız maksimum keyfiyyət səviyyəsi 3-dən çox olmayan bina növlərini nəzərdən keçirin.

TİP SEÇİN, AVG (QLTY_JLEVEL)

STATUS = 1

MAX (QLTY_LEVEL) VAR<= 3

Nəticə:

TYPE AVG(QLTY_LEVEL)

Mağaza 1

Yaşayış binası 3

Qeyd edək ki, FROM bəndindən başlayaraq bəndlər ardıcıllıqla yerinə yetirilir və sonra SELECT bəndi tətbiq edilir. Beləliklə, BİNA cədvəlinə WHERE bəndi tətbiq edilir və STATUS-un 1-dən fərqli olduğu bütün sətirlər silinir. Qalan sıralar TYPE üzrə qruplaşdırılıb; eyni TYPE dəyəri olan bütün sətirlər eyni qrupda bitir. Beləliklə, hər TYPE dəyəri üçün bir olmaqla bir neçə qrup yaradılır. Daha sonra HAVING bəndi hər qrupa tətbiq edilir və maksimum keyfiyyət səviyyəsi dəyəri 3-dən çox olan qruplar çıxarılır. Nəhayət, SELECT bəndi qalan qruplara tətbiq edilir.

7. Daxili funksiyalar və alt sorğular

Daxili funksiyalar yalnız SELECT bəndində və ya HAVING əmrində istifadə edilə bilər. Bununla belə, daxili funksiyadan ibarət SELECT bəndi alt sorğunun bir hissəsi ola bilər. Belə bir alt sorğunun nümunəsinə baxaq:

Sorğu: Hansı işçilər orta saatlıq tarifdən yüksəkdir?

İŞÇİ_NAME SEÇİN

HRLY_RATE >

(SEÇ AVG(HRLY_RATE)

Nəticə:

H. Kolumb

Qeyd edək ki, alt sorğu əsas sorğu ilə əlaqəli deyil. Alt sorğu tam olaraq bir dəyəri qaytarır - orta saatlıq tarif. Əsas sorğu işçini yalnız onun dərəcəsi hesablanmış ortalamadan çox olduqda seçir.

Əlaqəli sorğular daxili funksiyalardan da istifadə edə bilər:

Sorğu: Hansı işçinin eyni menecerin tabeliyində olan işçilər arasında saatlıq tarifi orta saatlıq tarifdən yüksəkdir?

Bu halda, bütün işçilər üçün bir orta saatlıq tarifi hesablamaq əvəzinə, eyni rəhbərə hesabat verən hər bir işçi qrupu üçün orta tarifi hesablamalıyıq. Üstəlik, əsas sorğu ilə nəzərdən keçirilən hər bir işçi üçün hesablamamız yenidən aparılmalıdır:

A. İŞÇİ_NAME SEÇİN

SQL sorğuları bir-birinizə yerləşdirməyə imkan verir. Tipik olaraq, alt sorğu predikatın doğru olub olmadığını yoxlamaq üçün yoxlanılan tək bir dəyər qaytarır.

Axtarış terminlərinin növləri:
. Alt sorğunun nəticəsi ilə müqayisə (=, >=)
. Alt sorğunun nəticələrinə aidiyyətin yoxlanılması (IN)
. Mövcudluq yoxlanışı (VAR)
. Çoxsaylı (kəmiyyət) müqayisə (HƏR, BÜTÜN)

İç-içə sorğular haqqında qeydlər:
. Alt sorğu yalnız bir sütun seçməlidir (mövcud predikatı olan alt sorğu istisna olmaqla) və onun nəticə məlumat növü predikatda göstərilən dəyərin məlumat növünə uyğun olmalıdır.
. Bəzi hallarda tək dəyərin qaytarılmasını təmin etmək üçün DISTINCT açar sözündən istifadə edə bilərsiniz.
. Siz alt sorğuya ORDER BY və ya UNION bəndini daxil edə bilməzsiniz.
. Alt sorğu axtarış şərtinin solunda və ya sağında yerləşə bilər.
. Alt sorğular GROUP BY bəndi olmadan toplama funksiyalarından istifadə edə bilər ki, bu da istənilən sayda sətir, xüsusi IN predikatı və sütun əsaslı ifadələr üçün avtomatik olaraq xüsusi dəyər qaytarır.
. Mümkün olduqda, alt sorğular yerinə JOIN cədvəl birləşmələrindən istifadə etməlisiniz.

İç-içə sorğular üçün nümunələr:

SNum=(Satış Adamlarından SNum SEÇİN HARƏDƏ SName='Motika')
SNum IN OLAN Sifarişlərdən * SEÇİN (Satış İnsanlarından SNum SEÇİN WHERE Şəhər='London')
SNum=(CNum=2001) OLAN Sifarişlərdən * SEÇİN
* HARƏDƏ Sifarişlərdən SEÇİN Amt>(Odate=10/04/1990 Sifarişlərdən AVG(Amt) SEÇİN)
SEÇİN * Müştəridən CNum=(Satış Adamlarından SNum+1000 SEÇİN WHERE SName='Serres')

2) Əlaqədar alt sorğular

SQL-də siz xarici sorğudan cədvələ istinad edən alt sorğular yarada bilərsiniz. Bu halda, alt sorğu bir neçə dəfə, xarici sorğudan hər cədvəl sətri üçün bir dəfə yerinə yetirilir. Buna görə də, alt sorğunun indeksdən istifadə etməsi vacibdir. Alt sorğu xarici cədvəllə eyni cədvələ daxil ola bilər. Əgər xarici sorğu nisbətən az sayda sıra qaytarırsa, o zaman əlaqəli alt sorğu əlaqəsizdən daha sürətli olacaq. Əgər alt sorğu az sayda sıra qaytarırsa, əlaqəli sorğu əlaqəsiz sorğudan daha yavaş olacaq.

Əlaqədar alt sorğular üçün nümunələr:

SEÇ * FROM SalesPeople Main 1(SEÇ AVG(Amt) FROM Sifarişlər O2 WHERE O2.CNum=O1.CNum) //dəyəri verilmiş müştəri üçün orta sifariş dəyərindən çox olan bütün sifarişləri qaytarır

3) Mövcud predikat

Sintaktik forma: MÖVCUDDUR ()

Predikat alt sorğunu arqument kimi qəbul edir və əgər alt sorğunun çıxışı varsa doğru, əks halda isə false kimi qiymətləndirir. Alt sorğu bir dəfə yerinə yetirilir və bir neçə sütundan ibarət ola bilər, çünki onların dəyərləri yoxlanılmır, lakin satırların olmasının nəticəsi sadəcə qeyd olunur.

EXISTS predikatı ilə bağlı qeydlər:
. EXISTS TRUE və ya FALSE qaytaran predikatdır və tək və ya digər Boolean ifadələri ilə birlikdə istifadə edilə bilər.
. EXISTS öz alt sorğusunda toplama funksiyalarından istifadə edə bilməz.
. Əlaqəli alt sorğularda EXISTS predikatı xarici cədvəlin hər sətri üçün yerinə yetirilir.
. Siz EXISTS predikatını cədvəl birləşmələri ilə birləşdirə bilərsiniz.

EXISTS predikatı üçün nümunələr:

SEÇİN * MÖVCUD MÜŞTƏRİNDƏN (SEÇ * Müştəridən WHERE Şəhər=’San Xose’) – əgər onlardan hər hansı biri San Xosedə yaşayırsa, bütün müştəriləri qaytarır.
MÖVCUD OLMAYAN YERDƏ İLK MÜŞTERİDƏN DISTINCT SNum SEÇİN (SEÇ * FROM Müştəri Göndər HERƏ Send.SNum=First.SNum AND Send.CNumFirst.CNum) – yalnız bir müştəriyə xidmət göstərən satıcıların sayını qaytarır.
DISTINCT F.SNum, SName, F.City FROM SalesPeople F, Mövcud olduğu Müştəri S (SEÇ * Müştəri T HARADA S.SNum=T.SNum VƏ S.CNumT.CNum VƏ F.SNum=S.SNum) – qaytarır bir neçə müştəriyə xidmət göstərən bütün satıcıların nömrələri, adları və yaşayış şəhərləri.
Mövcud YERDƏ SalesPeople Frst FROM * SEÇİN (SEÇ * Müştəridən Göndər Frst.SNum=Send.SNum VƏ 1

4) Kəmiyyət müqayisəsinin predikatları

Sintaktik forma: (=|>|=|) HƏMİSİ| ()

Bu predikatlar arqument kimi alt sorğudan istifadə edir, lakin EXISTS predikatı ilə müqayisədə onlar əlaqə predikatları ilə (=,>=) birlikdə istifadə olunur. Bu mənada onlar IN predikatına bənzəyir, lakin yalnız alt sorğularla istifadə olunur. Standart HƏRƏ əvəzinə SOME açar sözünü istifadə etməyə imkan verir, lakin bütün DBMS-lər bunu dəstəkləmir.

Müqayisə predikatlarına dair qeydlər:
. Əgər alt sorğunun icrası zamanı seçilmiş hər bir dəyər xarici sorğu predikatında göstərilən şərti ödəyirsə, BÜTÜN predikatı TRUE kimi qiymətləndirir. Ən çox bərabərsizliklərlə istifadə olunur.
. Əgər alt sorğunun icrası zamanı seçilmiş ən azı bir dəyər xarici sorğu predikatında göstərilən şərti ödəyirsə, HƏR predikatı DOĞRU kimi qiymətləndirir. Ən çox bərabərsizliklərlə istifadə olunur.
. Əgər alt sorğu heç bir sətir qaytarmırsa, onda ALL avtomatik olaraq TRUE dəyərini qəbul edir (müqayisə şərtinin təmin edildiyi hesab olunur), HƏRİ üçün isə FALSE dəyərini qəbul edir.
. Əgər heç bir sətir üçün müqayisə TRUE-dursa və NULL dəyəri olan bir və ya bir neçə sətir varsa, HƏR NƏNİYYƏTİ UNKNOWN verir.
. Əgər heç bir sətir üçün müqayisə YANLIŞ-dırsa və NULL dəyəri olan bir və ya bir neçə sətir varsa, HƏMMI UNKNOWN-u qaytarır.

Kəmiyyət müqayisəsi predikatı üçün nümunələr:

Şəhər=HƏR YERİ Satıcılardan * SEÇİN (Müştəridən Şəhər SEÇİN)
* HARADA HAMISI OLAN Sifarişlərdən SEÇİN(Müştəridən Reytinq SEÇİN REYTİN HARADA Şəhər='Roma')

5) Unikallıq predikatı

UNİKAL|FƏRQLİ ()

Predikat alt sorğunun çıxış məlumatlarında unikallığı (dublikatların olmamasını) yoxlamaq üçün istifadə olunur. Üstəlik, UNIQUT predikatında NULL dəyərləri olan sətirlər unikal hesab olunur və DISTINCT predikatında iki qeyri-müəyyən dəyər bir-birinə bərabər hesab olunur.

6) Predikatı uyğunlaşdırın

MATÇ ()

MATCH predikatı sorğu sətirinin dəyərinin alt sorğu nəticəsində yaranan hər hansı sətirin dəyərinə uyğun olub-olmadığını yoxlayır. Bu alt sorğu IN VƏ HƏR HƏR predikatlarından onunla fərqlənir ki, o, bəzi NULL dəyərləri olan sətirlər arasında baş verə biləcək “qismən” (PARTIAL) uyğunluqları emal etməyə imkan verir.

7) FROM bölməsindəki sorğular

Əslində, cədvəl istinadına icazə verilən yerdə alt sorğudan istifadə etmək qanunidir.

CName, Tot_Amt FROM Müştəri SEÇİN, (CNum, SUM(Amt) AS Tot_Amt FROM CNum GROUP BY CNum) HERE City='London' AND Customer.CNum=Orders.CNum
//alt sorğu hər bir müştərinin Londondan verdiyi sifarişlərin ümumi məbləğini qaytarır.

8) Rekursiv sorğular

REKURSİV İLƏ
Q1 SEÇİLƏN KİMİ … YERDƏN … HARADAN …
Q2 SEÇİLƏN KİMİ … YERDƏN … HARADAN …




Üst