CodeGym /Kurslar /SQL SELF /FROM içində subquery-lərdən istifadə

FROM içində subquery-lərdən istifadə

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

FROM içində subquery-lərdən istifadə

Gəlin bir az da dərinliyə gedək: FROM içində subquery-lərdən necə istifadə etməyi baxaq. Bu SQL developer-ların ən çox istifadə etdiyi yanaşmalardan biridir, çünki beləliklə güclü müvəqqəti cədvəlləri birbaşa "yerində" yarada və onları sanki bazada mövcud cədvəllər kimi istifadə edə bilərsən.

Təsəvvür elə ki, bir hesabat hazırlayırsan və orada hesablama, qruplaşdırma və ya filtrasiya lazımdır, amma əlavə müvəqqəti cədvəl yaratmaq istəmirsən. Nə etməli? Bax, burada FROM içində subquery-lər köməyə gəlir. Onlar sənə imkan verir:

  • Müvəqqəti olaraq datanı birləşdirmək və ya əsas sorğudan əvvəl aggregate etmək.
  • "Uçan" strukturlu dataset-lər yaratmaq.
  • Əməliyyatların sayını azaltmaq, yəni bazadan minimal aralıq data saxlanmasını tələb etmək.

FROM içində subquery-lər mini-cədvəllər kimi işləyir və əsas sorğuda istifadə oluna bilər. Bu, sanki modul konstruksiya yığmaq kimidir: tez, çevik və əlavə overhead olmadan :)

FROM içində subquery-lərin əsasları

FROM içində subquery-lərdə biz subquery yazıb müvəqqəti cədvəl (və ya subtable) yaradırıq və bu, ümumi sorğunun bir hissəsinə çevrilir. Bunun üçün 3 əsas addım var:

  1. Subquery-ni FROM hissəsində mötərizədə yazırsan.
  2. Subquery-yə alias (təxəllüs) verirsən.
  3. Bu alias-ı sanki tam cədvəl kimi istifadə edirsən.

Sintaksis

SELECT sütunlar
FROM (
    SELECT sütunlar
    FROM cədvəl
    WHERE şərt
) AS təxəllüs
WHERE xarici_şərt;

Qorxulu səsləndi? Gəlin nümunələrə keçək.

Nümunə: Tələbələr və orta bal

Tutaq ki, bizdə iki cədvəl var:

students (tələbələr haqqında məlumat — ad və ID):

student_id student_name
1 Alex
2 Anna
3 Dan

grades (tələbələrin qiymətləri):

grade_id student_id grade
1 1 80
2 1 85
3 2 90
4 3 70
5 3 75

İndi tapşırıq: tələbələrin siyahısını və onların orta balını almaq.

Əvvəlcə hər tələbənin orta balını hesablayan sadə subquery ilə başlaya bilərik, sonra onu əsas sorğuda istifadə edirik.

SELECT s.student_name, g.avg_grade
FROM (
    SELECT student_id, AVG(grade) AS avg_grade
    FROM grades
    GROUP BY student_id
) AS g
JOIN students AS s ON s.student_id = g.student_id;

Nəticə:

student_name avg_grade
Alex 82.5
Anna 90.0
Dan 72.5

"Uçan" müvəqqəti cədvəllər

FROM içində subquery-lər xüsusilə faydalıdır, əgər bir neçə səviyyədə data işləmək lazımdırsa. Məsələn, təkcə orta bal yox, həm də hər tələbə üçün maksimum balı hesablamaq istəyirsənsə — hamısını bir sorğuda.

SELECT g.student_id, g.avg_grade, g.max_grade
FROM (
    SELECT student_id, 
           AVG(grade) AS avg_grade, 
           MAX(grade) AS max_grade
    FROM grades
    GROUP BY student_id
) AS g;

Nəticə:

student_id avg_grade max_grade
1 82.5 85
2 90 90
3 72.5 75

Fikir ver, bu tam müvəqqəti cədvəl kimi işləyir və öz sütun adları var: avg_grademax_grade.

FROM içində subquery-ləri nə vaxt istifadə etmək daha yaxşıdır?

Aggregated data üçün. Əvvəlcə hesablama (məsələn, orta, cəmlər və ya maksimumlar) aparmaq, sonra nəticəni başqa cədvəllərlə birləşdirmək istəyirsənsə.

Data filtrasiya üçün. Əsas cədvəllə birləşdirmədən əvvəl datanı filtrasiya etmək lazım olanda.

Çətin sorğuları asanlaşdırmaq üçün. Çətin tapşırıqları mərhələlərə bölmək qarışıqlığın qarşısını alır.

Nümunə: İki səviyyəli tələbə hesabatı

Tutaq ki, orta balı 80-dən yuxarı olan tələbələri tapmaq istəyirik. Əvvəlcə orta balı hesablayan subquery yazırıq, sonra onu filterdə istifadə edirik.

SELECT s.student_name, g.avg_grade
FROM students AS s
JOIN (
    SELECT student_id, AVG(grade) AS avg_grade
    FROM grades
    GROUP BY student_id
) AS g ON s.student_id = g.student_id
WHERE g.avg_grade > 80;

Nəticə:

student_name avg_grade
Alex 82.5
Anna 90.0

İstifadə xüsusiyyətləri və tövsiyələr

Mütləq alias. Subquery-yə həmişə alias ver (məsələn, AS g), yoxsa PostgreSQL bu "müvəqqəti cədvələ" necə müraciət edəcəyini anlamayacaq.

Optimallaşdırma. FROM içində subquery-lər bəzən table join-lardan (JOIN) daha yavaş ola bilər, xüsusilə də subquery daxilində filtrasiya edirsənsə.

İndeksləmə. Join, indeks və filter üçün istifadə olunan sahələrin optimallaşdırıldığından əmin ol — bu performansa ciddi təsir edir.

Çətin sorğu nümunəsi: kurslar və tələbə sayı

İndi isə bir az daha çətin real tapşırıq edək. Təsəvvür elə ki, belə bir cədvəlimiz var:

courses (kursların siyahısı):

course_id course_name
1 SQL Basics
2 Python Basics

enrollments (tələbələrin kurslara yazılması):

student_id course_id
1 1
1 2
2 1

İndi isə hər kursa neçə tələbə yazılıb onu bilmək istəyirik.

SELECT c.course_name, e.students_count
FROM courses AS c
JOIN (
    SELECT course_id, COUNT(student_id) AS students_count
    FROM enrollments
    GROUP BY course_id
) AS e ON c.course_id = e.course_id;

Nəticə:

course_name students_count
SQL Basics 2
Python Basics 1

Ümid edirəm leksiya xoşuna gəldi... amma növbəti daha maraqlı olacaq :)

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