CodeGym /Kurslar /SQL SELF /SELECT içində SELECT istifadə ...

SELECT içində SELECT istifadə etmək

SQL SELF
Səviyyə , Dərs
Mövcuddur

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

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:

  1. Hər tələbə üçün onun adını və qiymətini alırıq (s.name, g.grade).
  2. SELECT MAX(grade) — bu subquery tələbənin qrupunda maksimal qiyməti qaytarır.
  3. 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:

  1. 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!
  2. İ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.
  3. 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:

  1. İndekslərdən istifadə et. Əgər subquery-lər datanı filterləyirsə, istifadə olunan sütunlarda indeks olduğuna əmin ol.
  2. Nəticələri cache-lə. Bəzən subquery-ləri VIEW və ya müvəqqəti cədvəllərə çıxarmaq daha məqsədəuyğundur.
  3. 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!

Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION