Təsəvvür elə, universitetdə analitiksən (axı biz universitet üçün verilənlər bazası düzəldirik, yadındadır?). Səndən tələb ediblər ki, sadəcə tələbələri və onların qiymətlərini göstərməyəsən, həm də cədvələ qrupda maksimal qiymət olan bir sütun əlavə edəsən ki, nəticələri rahat müqayisə etmək olsun. Bu işi necə həll edək? Əlbəttə, SELECT-də subquery-lər ilə!
SELECT-də subquery sənə əsas sorğu işləyərkən birbaşa dəyərləri hesablamağa imkan verir. Bu çox rahatdır, çünki bir sorğuda aggregat hesablama, çətin filterlər və hətta başqa data kolleksiyasını birləşdirə bilərsən.
SELECT-də nested query-lərin əsasları
SELECT-də subquery sözün əsl mənasında belə işləyir: bir SELECT-in nəticəsini başqa bir SELECT-in içinə qoyursan. Bu, nəticənin hər sətri üçün əlavə dəyərlər hesablamağa imkan verir.
Sadə bir nümunə. Deyək ki, bizdə belə bir students cədvəli var:
| student_id | name | group_id |
|---|---|---|
| 1 | Linda | 101 |
| 2 | Otto | 102 |
| 3 | Anna | 101 |
Və grades cədvəli:
| grade_id | student_id | grade |
|---|---|---|
| 1 | 1 | 5 |
| 2 | 1 | 4 |
| 3 | 2 | 3 |
| 4 | 3 | 5 |
| 5 | 3 | 4 |
Nümunə 1: Qrupda maksimal qiyməti əlavə etmək
Tapşırıq: tələbələrin adını, qiymətini və qrupda maksimal qiyməti göstər ki, hər tələbənin qiymətinin qrupun ən yaxşı nəticəsindən nə qədər fərqləndiyini görmək olsun.
SQL kodu:
SELECT
s.name AS student_name,
g.grade AS student_grade,
(
SELECT MAX(grade) -- bu sorğu yalnız bir dəyər qaytarır
FROM grades
INNER JOIN students ON grades.student_id = students.student_id
WHERE students.group_id = s.group_id
) AS max_group_grade
FROM
students s
INNER JOIN
grades g ON s.student_id = g.student_id;
Burda nə baş verir:
- Hər tələbə üçün onun adını və qiymətini alırıq (
s.name,g.grade). SELECT MAX(grade)— bu subquery tələbənin qrupunda maksimal qiyməti qaytarır.- Subquery əsas sorğunun hər sətri üçün işləyir və
WHERE students.group_id = s.group_idşərtindən istifadə edir ki, yalnız bir qrupa baxılsın.
Nümunə 2: Qrup üzrə orta qiymət
Analitiklər üçün daha faydalı olmaq istəyirsən? Gəlin çıxışa təkcə maksimal qiyməti yox, həm də qrup üzrə orta qiyməti əlavə edək.
SQL kodu:
SELECT
s.name AS student_name,
g.grade AS student_grade,
(
SELECT AVG(grade)
FROM grades
INNER JOIN students ON grades.student_id = students.student_id
WHERE students.group_id = s.group_id
) AS avg_group_grade
FROM
students s
INNER JOIN
grades g ON s.student_id = g.student_id;
İndi isə:
MAX()əvəzinəAVG()istifadə edirik ki, qrup üzrə orta qiyməti hesablayaq.- "Canlı" data analizi alırıq.
Məhdudiyyətlər və tövsiyələr
SELECT-də subquery-lər güclüdür, amma istifadə edəndə diqqətli olmaq lazımdır:
- Performans. Hər subquery əsas sorğunun hər sətri üçün işləyir. Əgər cədvəllər böyükdürsə, SQL sorğusunun işləmə sürəti xeyli azala bilər. Məsələn, cədvəldə 1000 tələbə varsa, subquery 1000 dəfə işləyəcək!
- İndekslər. Belə sorğuların sürətli işləməsi üçün
WHEREşərtində istifadə olunan sütunlarda düzgün indekslər olmalıdır. - Oxunaqlılıq. Həddindən artıq nested query-lərdən qaç. Əgər subquery-lər çox mürəkkəbləşirsə, onları
FROM-a çıxarmağı və ya müvəqqəti cədvəllər yaratmağı düşün.
İstifadə nümunələri
Gəlin bir neçə maraqlı case-ə də baxaq.
Nümunə 3: Hər tələbənin kurs sayı
Bir cədvəl çıxarırıq, burada hər tələbə üçün neçə kursa yazıldığını göstəririk. enrollments cədvəli tələbələrlə student_id ilə bağlıdır:
| student_id | course_id |
|---|---|
| 1 | 201 |
| 1 | 202 |
| 2 | 201 |
| 3 | 203 |
SQL kodu:
SELECT
s.name AS student_name,
(
SELECT COUNT(*)
FROM enrollments
WHERE enrollments.student_id = s.student_id
) AS course_count
FROM
students s;
Burada subquery hər tələbə üçün enrollments cədvəlində neçə qeyd olduğunu sayır.
Nümunə 4: Hər tələbə üçün "əlaçı" flag-ı
Göstərək ki, tələbə əlaçıdır ya yox. Qoy əlaçı üçün kriteriya belə olsun — bütün qiymətləri 5 olan tələbə.
SQL kodu:
SELECT
s.name AS student_name,
(
SELECT CASE
WHEN MIN(g.grade) = 5 THEN 'Əlaçı'
ELSE 'Əlaçı deyil'
END
FROM grades g
WHERE g.student_id = s.student_id
) AS status
FROM
students s;
Burada nested CASE istifadə olunur ki, yalnız bütün qiymətləri 5 olan tələbələrə "Əlaçı" statusu verilsin.
SELECT-də subquery-lərin optimizasiyası
Artıq qeyd etdik ki, performans problem ola bilər. Budur, bir neçə faydalı məsləhət:
- İndekslərdən istifadə et. Əgər subquery-lər datanı filterləyirsə, istifadə olunan sütunlarda indeks olduğuna əmin ol.
- Nəticələri cache-lə. Bəzən subquery-ləri
VIEWvə ya müvəqqəti cədvəllərə çıxarmaq daha məqsədəuyğundur. - Daha az nested query. Əgər mümkündürsə, çox nested query istifadə etmə, daha sadə yanaşma seç.
SELECT-də subquery-lər hesablamalar və data analizi üçün böyük imkanlar açır. Onlar resurs tələb edə bilər, amma düzgün optimizasiya ilə SQL-i daha ifadəli və çevik edir. Ona görə də, çəkinmədən eksperiment elə və sorğularını daha yaxşı et!
GO TO FULL VERSION