IlmHamroh
JavaScript Full-stack/26-qism. SQL va PostgreSQL10/64-dars18 daqiqa
Mundarija (37)

SQL tili va buyruq turlari: DDL, DML, DQL, DCL, TCL va bajarilish tartibi

Qisqacha: SQL (Structured Query Language) — relatsion bazalar bilan gaplashish tili. U deklarativ: siz natija qanday bo'lishi kerakligini aytasiz, uni qanday topishni baza o'zi tanlaydi. Buyruqlar besh guruhga bo'linadi: tuzilma (DDL — CREATE, ALTER, DROP), ma'lumot (DML — INSERT, UPDATE, DELETE), so'rov (DQL — SELECT), ruxsat (DCL — GRANT, REVOKE) va tranzaksiya (TCL — BEGIN, COMMIT, ROLLBACK). SELECT yozilish tartibida emas, boshqa tartibda bajariladi: FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT.

Bu darsda

  • Deklarativ va imperativ yondashuv farqini JS va SQL misolida tushuntirasiz.
  • SQL buyruqlarini beshta guruhga ajrata olasiz va har biridan misol keltirasiz.
  • SQL sintaksisining asosiy qoidalarini (registr, qo'shtirnoq turlari, izohlar, ;) bilasiz.
  • SELECT qismlari qaysi tartibda bajarilishini va nega WHERE da taxallus ishlamasligini aytasiz.
  • SQL standarti va dialektlar (PostgreSQL, MySQL, SQLite, SQL Server) farqini taniysiz.

Oldin bilishingiz kerak: psql chuqur, Relatsion model, filter: shart bo'yicha tanlash.

1. Nega bu kerak?

Oldingi darslarda SQL buyruqlarini "o'qib tushunish" darajasida ko'rdik. Endi o'zingiz yozasiz. Lekin buyruqlarni birma-bir yodlashdan oldin tilning qanday fikrlashini tushunish kerak. Aks holda shunday xatolar boshlanadi: "nega WHERE da o'zim bergan nomni tanimaydi?", "nega qo'shtirnoqdagi matnni ustun deb o'ylayapti?".

SQL — JavaScript'ga umuman o'xshamagan til. JS'da siz kompyuterga qadamlarni aytasiz: "massivni aylan, shartni tekshir, natijaga qo'sh". SQL'da esa natijani tasvirlaysiz: "shu shartga mos vazifalar kerak". Qanday topishni baza hal qiladi.

Hayotiy o'xshatish: taksi. Imperativ yo'l — haydovchiga har burilishni aytish: "to'g'ri, chapga, svetoforda o'ngga". Deklarativ yo'l — "Chorsu bozoriga" deyish. Yo'lni haydovchi (baza) o'zi tanlaydi — tirbandlikni, ta'mirlanayotgan ko'chani u yaxshiroq biladi.

2. Deklarativ til

2.1 Bir savol — ikki usul

Savol: "Aziz hali bajarmagan vazifalardan eng yangi uchtasining matni". JavaScript'da massiv bilan buni qadamma-qadam yozamiz. filter, map kabi metodlarni filter: shart bo'yicha tanlash va map: har elementni o'zgartirish darslarida o'rgangansiz:

js
const vazifalar = [
  { id: 1, egasi: 1, matn: "26-qismni boshlash", bajarildi: false,
    vaqt: "2026-10-01" },
  { id: 8, egasi: 1, matn: "Blog yozish", bajarildi: false,
    vaqt: "2026-10-05" },
  { id: 9, egasi: 1, matn: "Dori olib borish", bajarildi: true,
    vaqt: "2026-10-03" },
  { id: 12, egasi: 1, matn: "Jo'mrakni almashtirish",
    bajarildi: false, vaqt: "2026-10-07" },
  { id: 14, egasi: 2, matn: "IELTS mashqi", bajarildi: false,
    vaqt: "2026-10-04" },
  { id: 33, egasi: 1, matn: "SQL JOIN mashqlari", bajarildi: false,
    vaqt: "2026-10-14" },
];

const natija = vazifalar
  .filter((v) => v.egasi === 1 && !v.bajarildi) // qatorlarni tanlash
  .sort((a, b) => b.vaqt.localeCompare(a.vaqt)) // yangisi oldin
  .slice(0, 3)                                  // 3 tasi
  .map((v) => v.matn);                          // faqat matn

console.log(natija);

Konsolda:

text
[ 'SQL JOIN mashqlari', "Jo'mrakni almashtirish", 'Blog yozish' ]

Biz har qadamni o'zimiz tanladik: avval filtrlash, keyin saralash, keyin kesish. Agar massivda million element bo'lsa ham, kod butun massivni aylanadi — boshqa yo'lni bilmaydi.

SQL'da xuddi shu savol — kanon vazifalar bazasida (to'liq namuna ma'lumoti bilan). Natijani biz kanon bazasining nusxasida ishga tushirib oldik:

sql
SELECT matn
FROM vazifalar
WHERE egasi_id = 1 AND NOT bajarildi
ORDER BY yaratilgan_vaqt DESC
LIMIT 3;

Natija (PostgreSQL 17.6):

text
                      matn
------------------------------------------------
 Velosiped zanjirini moylash
 SQL JOIN mashqlarini yechish #o'qish
 Oshxonadagi jo'mrakni almashtirish #ta'mir #uy
(3 rows)

NOT bajarildi — JS'dagi !v.bajarildi ning o'zi: NOT mantiqiy qiymatni teskarisiga aylantiradi.

Bu yerda biz "qanday" haqida hech narsa demadik. Jadvalda indeks bo'lsa, baza butun jadvalni o'qimasdan to'g'ridan-to'g'ri kerakli qatorlarga boradi. Indeks qo'shilgan kuni so'rov o'zgarmaydi — faqat tezlashadi.

2.2 Bazaning rejasi: EXPLAIN

"Qanday" ni baza o'zi tanlashini ko'rish mumkin. So'rov oldiga EXPLAIN yozilsa, baza uni bajarmaydi — faqat rejasini (plan) ko'rsatadi. Misol uchun boshqa so'rovni olamiz: "har egada nechta vazifa bor, 5 tadan ko'plari, ko'pidan kamiga". Uning qismlarini (count(*), GROUP BY, HAVING) shu darsning «Bajarilish tartibi» bo'limida ochamiz — hozir faqat rejaga qarang. Chiqishda qatorlarning chap chetidagi nomlar muhim — Sort, HashAggregate, Seq Scan (kanon PostgreSQL 18.6 chiqishi; 17.6 da ham aynan shunday):

sql
EXPLAIN SELECT egasi_id, count(*) AS soni
FROM vazifalar
GROUP BY egasi_id
HAVING count(*) > 5
ORDER BY soni DESC;
text
                               QUERY PLAN
------------------------------------------------------------------------
 Sort  (cost=28.93..29.10 rows=67 width=16)
   Sort Key: (count(*)) DESC
   ->  HashAggregate  (cost=24.40..26.90 rows=67 width=16)
         Group Key: egasi_id
         Filter: (count(*) > 5)
         ->  Seq Scan on vazifalar  (cost=0.00..19.60 rows=960 width=8)
(6 rows)

Nima bo'ldi? Rejani pastdan yuqoriga o'qing: jadval to'liq o'qiladi (Seq Scan), egalar bo'yicha guruhlanadi (HashAggregate), saralanadi (Sort). cost va rows — bazaning taxminlari, ular hozir muhim emas. Biz bu qadamlarni yozmadik — planner (rejalashtiruvchi) ularni o'zi tanladi. Rejalarni EXPLAIN ANALYZE'ni o'qish darsida o'qishni o'rganamiz.

Tekshirib ko'ring: JS kodimizda .sort va .filter o'rnini almashtirsak (avval saralash, keyin filtrlash), natija o'zgaradimi? Tezlik-chi? SQL'da bunday tanlov kimga tegishli?

Javob

Natija o'zgarmaydi, lekin tezlik yomonlashadi: avval hamma element saralanadi, keyin ko'pi tashlab yuboriladi. JS'da bu tanlov — sizniki. SQL'da esa WHERE va ORDER BY ni qaysi tartibda yozsangiz ham, bajarish tartibini baza tanlaydi va doim arzonrog'ini oladi. Deklarativ tilning kuchi shunda.

3. Buyruqlarning besh guruhi

3.1 Guruhlar xaritasi

flowchart TD
  S[SQL buyruqlari] --> DDL[DDL — tuzilma<br/>CREATE, ALTER, DROP]
  S --> DML[DML — ma'lumot<br/>INSERT, UPDATE, DELETE]
  S --> DQL[DQL — so'rov<br/>SELECT]
  S --> DCL[DCL — ruxsat<br/>GRANT, REVOKE]
  S --> TCL[TCL — tranzaksiya<br/>BEGIN, COMMIT, ROLLBACK]

Nimaga qarang: har guruh o'z savoliga javob beradi. DDL — "jadval qanday tuzilgan?", DML — "ichida nima bor?", DQL — "menga nimani ko'rsat?", DCL — "kim nima qila oladi?", TCL — "qaysi o'zgarishlar birga?". Ba'zi kitoblarda SELECT ham DML'ga kiritiladi — bu kelishuv masalasi, mohiyat bir xil.

Kanon beshala guruhni bitta kichik tajribada sinadi. Quyida — o'sha chiqish, bo'laklarga bo'lingan.

3.2 DDL — tuzilma

DDL (Data Definition Language — ma'lumotni ta'riflash tili) — jadvallar, ustunlar, indekslar va boshqa obyektlarni yaratadi, o'zgartiradi, o'chiradi:

sql
CREATE TABLE t10_eslatma (id int PRIMARY KEY, matn text);
ALTER TABLE t10_eslatma ADD COLUMN muhim boolean DEFAULT false;

psql javoblari:

text
CREATE TABLE
ALTER TABLE

CREATE TABLE — yangi jadval, ALTER TABLE — mavjudini o'zgartirish (bu yerda ustun qo'shildi). DROP TABLE — o'chirish. Ularni CREATE TABLE va cheklovlar va ALTER TABLE va sxemani o'zgartirish darslarida o'rganamiz.

3.3 DML va DQL — ma'lumot

DML (Data Manipulation Language — ma'lumot bilan ishlash tili) — qatorlarni qo'shadi, o'zgartiradi, o'chiradi. DQL (Data Query Language — so'rov tili) — ularni o'qiydi:

sql
INSERT INTO t10_eslatma (id, matn) VALUES (1, 'salom');
UPDATE t10_eslatma SET muhim = true WHERE id = 1;
SELECT * FROM t10_eslatma;

Natija:

text
INSERT 0 1
UPDATE 1
 id | matn  | muhim
----+-------+-------
  1 | salom | t
(1 row)

INSERT 0 1 — 1 qator qo'shildi (o'rtadagi 0 — tarixiy maydon, hozir doim 0). UPDATE 1 — 1 qator o'zgardi. SELECT * — "hamma ustunlar".

3.4 DCL — ruxsat

DCL (Data Control Language — boshqaruv tili) — kim nimaga ruxsatli ekanini belgilaydi. Kanon faqat o'qiy oladigan rol yaratdi:

sql
CREATE ROLE t10_oquvchi LOGIN;
GRANT SELECT ON t10_eslatma TO t10_oquvchi;
SET ROLE t10_oquvchi;
SELECT matn FROM t10_eslatma;
DELETE FROM t10_eslatma;
RESET ROLE;

Natija:

text
CREATE ROLE
GRANT
SET
 matn
-------
 salom
(1 row)

ERROR:  permission denied for table t10_eslatma
RESET

GRANT SELECT — faqat o'qishga ruxsat. SET ROLE — vaqtincha shu rol bo'lib ishlash. O'qish ishladi, o'chirish esa rad etildi. Tarjimasi: "t10_eslatma jadvali uchun ruxsat yo'q". CREATE ROLE ni texnik jihatdan DDL'ga ham kiritishadi — u obyekt yaratadi. Ilova uchun cheklangan rollarni Rollar va huquqlar darsida quramiz.

3.5 TCL — tranzaksiya va tranzaksion DDL

TCL (Transaction Control Language) — BEGIN, COMMIT, ROLLBACK. Ularni ACID, BASE, CAP va PACELC darsida ko'rdik. Postgres'ning bir xususiyati bor: DDL ham tranzaksiyada bekor qilinadi. Kanon jadvalni o'chirib, keyin bekor qildi:

sql
BEGIN;
DROP TABLE t10_eslatma;
ROLLBACK;
SELECT count(*) AS jadval_qaytdi FROM t10_eslatma;

Natija:

text
BEGIN
DROP TABLE
ROLLBACK
 jadval_qaytdi
---------------
             1
(1 row)

Jadval ichidagi bitta qator bilan birga qaytdi. Bu migratsiyalar uchun juda qulay: sxema faylining o'rtasida xato bo'lsa, butun fayl bekor bo'ladi. Hamma bazada bunday emas — MySQL'da DROP TABLE kabi DDL buyruqlari tranzaksiyani avtomatik yakunlaydi va ularni bekor qilib bo'lmaydi (MySQL hujjatidagi "implicit commit" qoidasi; kanon MySQL'ni sinamagan).

Tekshirib ko'ring: Quyidagilar qaysi guruhga kiradi: REVOKE, DELETE, DROP, ROLLBACK, SELECT?

Javob

REVOKE — DCL (ruxsatni qaytarib olish). DELETE — DML (qatorlarni o'chiradi, jadval qoladi). DROP — DDL (jadvalning o'zini o'chiradi). ROLLBACK — TCL. SELECT — DQL. DELETE va DROP ni adashtirmang: birinchisi ichini bo'shatadi, ikkinchisi jadvalni yo'q qiladi.

4. Sintaksis qoidalari

4.1 Registr va identifikatorlar

SQL kalit so'zlari registrga befarq: SELECT, select, Select — bir xil. Jadval va ustun nomlari (identifikatorlar) ham qo'shtirnoqsiz yozilsa, Postgres ularni kichik harfga aylantiradi:

sql
select ID, Matn from VAZIFALAR where Id = 29;

Natija:

text
 id |        matn
----+---------------------
 29 | Gaz to'lovi #to'lov
(1 row)

VAZIFALAR → vazifalar, Matn → matn — hammasi topildi. Kelishuv: kalit so'zlar KATTA harf bilan, nomlar kichik harf va _ bilan (yaratilgan_vaqt). Kursda shunday yozamiz.

Qo'shtirnoqli nom ("Vazifalar") esa aynan yozilganicha qoladi:

sql
SELECT * FROM "Vazifalar";
text
ERROR:  relation "Vazifalar" does not exist
LINE 1: SELECT * FROM "Vazifalar";
                      ^

Tarjimasi: "Vazifalar munosabati (jadvali) mavjud emas". Jadval vazifalar (kichik harf) nomi bilan yaratilgan. ^ belgisi xato qayerda ekanini ko'rsatadi. Shuning uchun jadval nomlarini doim kichik harf bilan yarating va qo'shtirnoqsiz yozing.

4.2 Qo'shtirnoqlar: ' matn, " nom

SQL'da ikki xil qo'shtirnoq ikki xil ma'noga ega:

Belgi Ma'nosi Misol
'…' matn qiymati 'Gaz to''lovi'
"…" identifikator (nom) "Vazifalar"

JS'da " va ' bir xil edi. SQL'da emas — bu boshlovchilarning eng ko'p qiladigan xatosi:

sql
SELECT id FROM vazifalar WHERE matn = "Gaz to'lovi #to'lov";
text
ERROR:  column "Gaz to'lovi #to'lov" does not exist
LINE 1: SELECT id FROM vazifalar WHERE matn = "Gaz to'lovi #to'lov";
                                              ^

Baza "…" ichidagi matnni ustun nomi deb qidirdi. Matnni '…' ga olish kerak. Matn ichidagi apostrof ikkilantiriladi — o'zbekcha matnlarda bu har qadamda kerak:

sql
SELECT 'Ali''ning vazifasi' AS izoh;
text
       izoh
-------------------
 Ali'ning vazifasi
(1 row)

Bu blokdagi uchta natijani biz kanon bazasining nusxasida ishga tushirib oldik (PostgreSQL 17.6).

4.3 Izohlar va ;

  • -- matn — qator oxirigacha izoh (JS'dagi //).
  • /* matn */ — ko'p qatorli izoh.
  • ; — buyruq tugadi. Bitta faylda ko'p buyruq bo'lsa, ular ; bilan ajratiladi.

AS — taxallus (alias): natijadagi ustunga yangi nom berish (count(*) AS soni). count(*) — qatorlar soni (JS'dagi massiv.length ga o'xshash). Ikkalasi keyingi bo'limda muhim bo'ladi.

5. Bajarilish tartibi

5.1 Yozish tartibi va bajarish tartibi

SELECT so'rovini biz shu tartibda yozamiz:

text
SELECT ... FROM ... WHERE ... GROUP BY ... HAVING ...
ORDER BY ... LIMIT ...;

Baza esa uni mantiqan boshqa tartibda bajaradi:

flowchart LR
  A[1. FROM] --> B[2. WHERE]
  B --> C[3. GROUP BY]
  C --> D[4. HAVING]
  D --> E[5. SELECT]
  E --> F[6. ORDER BY]
  F --> G[7. LIMIT]

Nimaga qarang: SELECT beshinchi o'rinda. Avval jadval olinadi (FROM), qatorlar filtrlanadi (WHERE), guruhlanadi (GROUP BY), guruhlar filtrlanadi (HAVING), shundan keyingina ustunlar tanlanadi va taxalluslar paydo bo'ladi (SELECT), oxirida saralanadi va kesiladi.

Bu — mantiqiy tartib: qaysi qism qaysi nomlarni "ko'radi". Planner ishni ichkarida boshqacha tashkil qilishi mumkin, lekin natija har doim shu tartibdagidek bo'ladi. GROUP BY va HAVING ni Agregatlar, GROUP BY va HAVING darsida chuqur o'rganamiz. Hozir ularni "guruhlash" va "guruhni filtrlash" deb o'qing.

5.2 Nega WHERE da taxallus ishlamaydi

Kanon "3 tadan ko'p vazifasi bor egalar" ni shunday so'radi:

sql
SELECT egasi_id, count(*) AS soni
FROM vazifalar
WHERE soni > 3
GROUP BY egasi_id;

Natija:

text
ERROR:  column "soni" does not exist
LINE 3: WHERE soni > 3
              ^

Tarjimasi: "soni ustuni mavjud emas". Lekin biz uni yozdik-ku! Bajarilish tartibiga qarang: WHERE — 2-qadam, soni taxallusi esa SELECT da — 5-qadam. WHERE ishlayotganda soni hali tug'ilmagan. Bundan tashqari, WHERE alohida qatorlarni filtrlaydi, count(*) esa guruh natijasi — guruhlar hali yo'q.

Guruh bo'yicha shart HAVING ga yoziladi (4-qadam, guruhlar tayyor):

sql
SELECT egasi_id, count(*) AS soni
FROM vazifalar
GROUP BY egasi_id
HAVING count(*) > 5
ORDER BY soni DESC;

Natija:

text
 egasi_id | soni
----------+------
        1 |    9
        3 |    6
        5 |    6
        2 |    6
(4 rows)

HAVING da ham taxallus emas, count(*) ning o'zi yozildi — SELECT hali ishlamagan. ORDER BY soni esa ishladi: u 6-qadam, SELECT dan keyin.

E'tibor bering: soni bir xil (6) bo'lgan uchta qator 3, 5, 2 tartibida chiqdi — tasodifiy. Relatsion model darsidagi qoida: tartib faqat ORDER BY da yozilgan narsaga kafolatlanadi. Barqaror tartib uchun ikkinchi kalit qo'shiladi:

sql
SELECT egasi_id, count(*) AS soni
FROM vazifalar
GROUP BY egasi_id
ORDER BY soni DESC, egasi_id
LIMIT 3;

Natija:

text
 egasi_id | soni
----------+------
        1 |    9
        2 |    6
        3 |    6
(3 rows)

Tekshirib ko'ring: SELECT matn AS m FROM vazifalar ORDER BY m; ishlaydimi? SELECT matn AS m FROM vazifalar WHERE m LIKE 'Gaz%'; chi?

Javob

Birinchisi ishlaydi: ORDER BY (6-qadam) SELECT dan (5-qadam) keyin, m allaqachon bor. Ikkinchisi column "m" does not exist xatosini beradi: WHERE (2-qadam) m paydo bo'lishidan oldin ishlaydi. To'g'risi: WHERE matn LIKE 'Gaz%'.

6. Standart va dialektlar

6.1 Tarix

SQL 1970-yillarda IBM'da SEQUEL nomi bilan yaratilgan (Donald Chamberlin va Raymond Boyce, Codd'ning relatsion modeli asosida). 1986-yilda ANSI, 1987-yilda ISO standarti bo'ldi. O'shandan beri standart yangilanib boradi; oxirgi versiyasi — SQL:2023 (JSON va graf so'rovlari bo'yicha qo'shimchalar bilan).

Har baza standartning katta qismini qo'llaydi va o'z kengaytmalarini qo'shadi. Shunday "shevalar"ni dialekt deyishadi.

6.2 Dialektlar farqi

Bir xil ish turli bazalarda:

Ish PostgreSQL MySQL SQL Server
birinchi N qator LIMIT 3 LIMIT 3 TOP 3
registrsiz qidiruv ILIKE LIKE* LIKE*
nom qo'shtirnog'i "nom" `nom` [nom]
qo'shilgan qatorni qaytarish RETURNING yo'q OUTPUT

* MySQL va SQL Server'da LIKE registrga befarqligi sozlamaga (collation) bog'liq. Jadval hujjatlarga tayanadi — kanon faqat PostgreSQL'ni sinagan.

Standart usul ham bor: LIMIT o'rniga FETCH FIRST n ROWS ONLY. Postgres ikkalasini tushunadi:

sql
SELECT matn FROM vazifalar
WHERE matn ILIKE '%bozor%'
ORDER BY id
FETCH FIRST 2 ROWS ONLY;

Natija:

text
                   matn
------------------------------------------
 Bozordan kartoshka va piyoz olish #bozor
 Bozordan meva olish #bozor
(2 rows)

ILIKE — Postgres'ga xos: registrga befarq qidiruv (bozor so'rovi Bozordan ni topdi). Bu kursda Postgres dialektini o'rganamiz, lekin standart qismni alohida belgilab boramiz — boshqa bazaga o'tganingizda bilimning 80–90 foizi o'zgarmaydi.

6.3 SQL va ORM

Ko'p loyihada SQL to'g'ridan-to'g'ri yozilmaydi — ORM yoki so'rov quruvchi (Prisma, Drizzle, Kysely) uni JS/TS koddan yasaydi. Ularni 27-qismda o'rganamiz. Lekin ular ichkarida baribir SQL yuboradi. Sekin so'rov, kutilmagan natija yoki xato chiqqanda — SQL'ni bilgan dasturchi muammoni topadi, bilmagani esa ORM hujjatini aylanib yuradi.

7. SQL qadami: vazifalar fayllari qaysi guruhda

Kanon vazifalar loyihasida SQL fayllar guruhlar bo'yicha ajratilgan:

Fayl Guruh Nima
sql/001-jadvallar.sql DDL jadvallar va cheklovlar
sql/003-namuna-asosiy.sql DML namuna ma'lumot (seed)
sorovlar/*.sql DQL darslardagi so'rovlar

Sxema fayllari bir marta qo'llanadi va keyin o'zgartirilmaydi — o'zgarish kerak bo'lsa, yangi raqamli fayl qo'shiladi (004-…). Har fayl psql chuqur darsidagi psql -X -1 -v ON_ERROR_STOP=1 -f bilan, bitta tranzaksiyada qo'llanadi — tranzaksion DDL tufayli yarim qo'llangan fayl bo'lmaydi. Birinchi DDL fayl CREATE TABLE va cheklovlar darsida yoziladi.

8. Ko'p uchraydigan xatolar

8.1 Matn uchun "…"

column "…" does not exist — va qo'shtirnoq ichidagi matn ustun nomi sifatida ko'rsatilgan. Matnni '…' ga oling.

8.2 Apostrofni ikkilantirmaslik

'Gaz to'lovi' — Postgres satrni 'Gaz to' da tugagan deb o'qiydi, lovi' dagi apostrof esa yangi satr ochadi va u yopilmaydi: unterminated quoted string (biz sinadik, PostgreSQL 17.6). To'g'risi: 'Gaz to''lovi'. Ilova kodida esa matnni hech qachon SQL satriga qo'lda qo'shmang — parametrlardan foydalaning (Parametrli so'rovlar va SQL injection).

8.3 WHERE da taxallus yoki agregat

column "soni" does not exist yoki aggregate functions are not allowed in WHERE. Taxallus o'rniga ifodaning o'zini yozing; agregat sharti — HAVING ga.

8.4 DELETE o'rniga DROP (yoki aksincha)

DROP TABLE vazifalar — jadval va hamma ma'lumot yo'qoladi. DELETE FROM vazifalar (shartsiz) — jadval qoladi, ichi bo'shaydi. Ikkalasi ham xavfli; xavfsiz yo'lini UPDATE va DELETE xavfsiz darsida o'rganamiz.

8.5 Boshqa dialektdan nusxa olish

Internetdagi javob MySQL uchun bo'lishi mumkin: `nom`, AUTO_INCREMENT, TOP. Postgres'da ular ishlamaydi. Javobning qaysi baza uchun ekaniga qarang.

9. Mashqlar

Mashqlar kurs/mashqlar/26/10-sql-tili/ da.

1-mashq (oson): guruhlang

Buyruqlarni guruhlarga ajrating (DDL, DML, DQL, DCL, TCL): CREATE TABLE, INSERT, GRANT, COMMIT, SELECT, ALTER TABLE, UPDATE, REVOKE, ROLLBACK, DROP TABLE, DELETE, BEGIN.

Yechim
  • DDL: CREATE TABLE, ALTER TABLE, DROP TABLE.
  • DML: INSERT, UPDATE, DELETE.
  • DQL: SELECT.
  • DCL: GRANT, REVOKE.
  • TCL: BEGIN, COMMIT, ROLLBACK.

2-mashq (o'rta): tartibni tiklang

Quyidagi bo'laklar aralashib ketgan. (a) To'g'ri yozish tartibida, (b) bajarilish tartibida joylashtiring:

LIMIT 5 · ORDER BY soni DESC · FROM vazifalar · HAVING count(*) > 2 · SELECT egasi_id, count(*) AS soni · WHERE NOT bajarildi · GROUP BY egasi_id

Yechim

(a) Yozish: SELECT egasi_id, count(*) AS soni → FROM vazifalar → WHERE NOT bajarildi → GROUP BY egasi_id → HAVING count(*) > 2 → ORDER BY soni DESC → LIMIT 5.

(b) Bajarilish: FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT.

Ma'nosi: "har egasining bajarilmagan vazifalari soni, 2 tadan ko'p bo'lganlari, ko'pidan kamiga, 5 tasi". Kanon bazasida (, egasi_id qo'shilgan barqaror tartib bilan) biz ishga tushirganda: egasi 1 — 5 ta, 2, 3 va 5 — 3 tadan.

3-mashq (qiyin): JS'dan SQL'ga

Ikki vazifa (vazifalar jadvali, namuna ma'lumoti bilan):

a) Bu JS zanjirini SQL'ga o'giring (v.egasi_id, v.yaratilgan_vaqt — jadval ustunlari):

js
vazifalar
  .filter((v) => v.egasi_id === 1 && v.bajarildi)
  .sort((a, b) => b.yaratilgan_vaqt - a.yaratilgan_vaqt)
  .slice(0, 2)
  .map((v) => ({ id: v.id, matn: v.matn }));

b) Bu so'rov xato beradi. Nega va qanday tuzatiladi? char_length — matn uzunligi (belgilar soni).

sql
SELECT id, char_length(matn) AS uzunlik
FROM vazifalar
WHERE uzunlik > 45
ORDER BY uzunlik DESC, id;

Natija:

text
ERROR:  column "uzunlik" does not exist
LINE 3: WHERE uzunlik > 45
              ^
Yechim

a) Natijani biz kanon namunasida ishga tushirdik (PG 17.6):

sql
SELECT id, matn
FROM vazifalar
WHERE egasi_id = 1 AND bajarildi
ORDER BY yaratilgan_vaqt DESC
LIMIT 2;

Natija:

text
 id |                     matn
----+----------------------------------------------
 28 | Elektr to'lovini Click orqali qilish #to'lov
  9 | Onamga dori olib borish #oila
(2 rows)

b) WHERE (2-qadam) uzunlik taxallusini ko'rmaydi — u SELECT da (5-qadam) paydo bo'ladi. LINE 3 va ^ xato qaysi qatorda ekanini ko'rsatadi. Tuzatish — ifodani takrorlash. ORDER BY da taxallus qolishi mumkin:

sql
SELECT id, char_length(matn) AS uzunlik
FROM vazifalar
WHERE char_length(matn) > 45
ORDER BY uzunlik DESC, id;

Natija:

text
 id | uzunlik
----+---------
  1 |      48
  2 |      47
 27 |      47
 10 |      46
 23 |      46
(5 rows)

Mos keluvchi qismlar: filter → WHERE, sort → ORDER BY, slice(0, 2) → LIMIT 2, map → SELECT ro'yxati. Lekin SQL'da ular yozilgan tartibda bajarilmaydi — bu yerda farq yo'q, chunki natija bir xil.

4-mashq: SQL qadami

O'z bazangizda (vazifalar, hali bo'sh) «Buyruqlarning besh guruhi» bo'limidagi tajribani takrorlang: t10_eslatma jadvalini yarating, qator qo'shing, BEGIN; DROP TABLE t10_eslatma; ROLLBACK; qiling va jadval qaytganini tekshiring. Oxirida jadvalni o'chiring — u vazifalar sxemasiga kirmaydi.

Yechim
sql
CREATE TABLE t10_eslatma (id int PRIMARY KEY, matn text);
INSERT INTO t10_eslatma VALUES (1, 'salom');
BEGIN;
DROP TABLE t10_eslatma;
ROLLBACK;
SELECT count(*) FROM t10_eslatma;
DROP TABLE t10_eslatma;

Natija:

text
CREATE TABLE
INSERT 0 1
BEGIN
DROP TABLE
ROLLBACK
 count
-------
     1
(1 row)

DROP TABLE

count — 1. Oxirgi DROP dan keyin \dt yana Did not find any relations. deydi — baza keyingi darsga toza.

10. Real ishda

  • Kod review: SQL'da WHERE va HAVING ni adashtirish, "…" bilan matn, ORDER BY siz LIMIT — tajribali reviewer birinchi ko'radigan joylar.
  • ORM bilan ishlaganda: ORM yuborgan SQL'ni logda ko'rib, uni o'qiy olish — sekin sahifani tuzatishning birinchi qadami.
  • Boshqa bazaga o'tganda: standart SQL (SELECT, JOIN, GROUP BY, FETCH FIRST) deyarli o'zgarmaydi; dialekt qismlari (ILIKE, RETURNING, ::) qayta yoziladi.
  • Intervyu savollari: "DDL va DML farqi?", "WHERE va HAVING farqi?", "SQL so'rovi qaysi tartibda bajariladi?" — bu uchtasi junior backend intervyularida eng ko'p beriladiganlardan.

Xulosa

  • SQL deklarativ: natijani tasvirlaysiz, yo'lni planner tanlaydi (EXPLAIN bilan ko'rinadi).
  • Besh guruh: DDL (tuzilma), DML (ma'lumot), DQL (SELECT), DCL (ruxsat), TCL (tranzaksiya); Postgres'da DDL ham ROLLBACK bo'ladi.
  • Kalit so'zlar va qo'shtirnoqsiz nomlar registrga befarq (nom kichik harfga aylanadi); '…' — matn, "…" — nom; apostrof — ''.
  • Bajarilish tartibi: FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT; shuning uchun WHERE da taxallus yo'q, ORDER BY da bor.
  • SQL standarti (oxirgisi SQL:2023) va dialektlar: LIMIT/TOP, ILIKE, RETURNING — bazaga xos.

Keyingi dars: PostgreSQL ma'lumot turlari — butun son, pul, matn, vaqt, UUID va JSON uchun to'g'ri turni tanlash.

Manbalar

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
SQL tili va buyruq turlari: DDL, DML, DQL, DCL, TCL va bajarilish tartibi — IlmHamroh