Ачааллж байна...
Түвшин 3-ын төгсгөлд хүрлээ. Энэ түвшинд та салгаж хадгалсан өгөгдлийг JOIN-оор нийлүүлж, INNER ба LEFT JOIN-ийн ялгааг, олон хүснэгтийн гинжийг, aggregate функцууд ба GROUP BY-ээр тоо гаргахыг, WHERE ба HAVING-ийн ялгааг, subquery-ийн гурван хэлбэрийг, index-ээр query хурдасгахыг сурсан. Түвшин 2-т зохиосон library2.db энэ бүх хугацаанд таны туршилтын талбар байсан.
Энэ дасгалд бид номын сангийн эрхлэгчийн ширээн дээр өдөр бүр хэрэгтэй таван тайланг бүтээнэ. Тайлан бүр Түвшин 3-ын хэд хэдэн хэрэгслийг хослуулна. Бүлэг 8-ын сүүлийн хичээлийн "урт query-г гүйцэтгэх дарааллаар угсар" гэсэн дадлыг энд бүрэн дагана: эхлээд FROM ба JOIN-ийг бичиж мөрийн тоог шалгах, дараа нь шүүлт, сагслалт, тооцоолол нэг нэгээр нэмэх. Тайлан бүрийн эцсийн query-г монголоор чангаар уншина.
Замдаа гурван жижиг шинэ хэрэгслийг таньна: огнооны зөрүү тооцох julianday(), NULL-ийг уншигдахуйц текстээр солих COALESCE()-ийн шинэ хэрэглээ, бүхэл тоон хуваалтын урхи. Эцэст нь таван тайланг reports.sql файл болгон хадгалж Git-д оруулна — Түвшин 2-ын library_schema.sql-ийн хамтрагч. library2.db-г нээгээрэй. Энэ дасгалд бид зөвхөн уншина.
Хоёр тайлан "өнөөдөр"-өөс хамаарна: хугацаа хэтэрсэн зээлүүд, тэдгээрийн хоцролтын хоног. Бодит програмд "өнөөдөр"-ийг SQLite-ийн date('now') функцээс авна. Гэвч тэгвэл таны үр дүн энэ хичээлийг уншиж буй өдрөөс хамааран өөр өөр гарна. Тиймээс бид тайлангийн өдрийг '2026-10-20' гэж тогтмол бичнэ — ингэснээр таны үр дүн хичээлийн үр дүнтэй үргэлж таарна. Бодит хэрэглээнд энэ текстийг date('now')-оор солиход хангалттай.
Асуулт: 10-р сарын 20-ны байдлаар хэн, ямар номоо, хэдэн хоног хоцорч байна вэ? Сануулга илгээхийн тулд имэйл хэрэгтэй.
Алхам 1 — хүснэгтүүд. Зээл (огноо), гишүүн (нэр, имэйл), ном (нэр) — гурван хүснэгт, Бүлэг 7-ийн сүүлийн хичээлийн гинж:
sql
SELECT *
FROM loans AS l
INNER JOIN members AS m ON l.member_id = m.id
INNER JOIN books AS b ON l.book_id = b.id;Мессеж: 8 rows returned — зээл бүрт нэг мөр, үржилтгүй. Суурь зөв.
Алхам 2 — шүүлт. Буцаагаагүй бөгөөд буцаах ёстой огноо нь тайлангийн өдрөөс өмнө:
sql
WHERE l.returned_on IS NULL
AND l.due_on < '2026-10-20'Мөрийн тоо 3 болно — зээл 4, 6, 7.
Алхам 3 — хоцролтын хоног. SQLite-д огноог шууд хасаж болохгүй — тэдгээр нь текст. julianday() функц огноог "түүхэн нэг өдрөөс хойш хэдэн хоног өнгөрсөн" гэсэн тоо болгон хувиргадаг тул хоёр огнооны julianday-г хасвал хоногийн зөрүү гарна. Үр дүн нь бутархай тоо (16.0) тул CAST-аар бүхэл тоо болгоно. Мөн Тэмүүлэн имэйлгүй — NULL нүд сануулгын жагсаалтад төөрөгдүүлэх тул Бүлэг 8-д сурсан COALESCE-ээр уншигдахуйц текстээр солино.
Эцсийн query:
sql
SELECT m.name,
COALESCE(m.email, 'имэйлгүй') AS email,
b.title,
l.due_on,
CAST(julianday('2026-10-20') - julianday(l.due_on) AS INTEGER) AS days_overdue
FROM loans AS l
INNER JOIN members AS m ON l.member_id = m.id
INNER JOIN books AS b ON l.book_id = b.id
WHERE l.returned_on IS NULL
AND l.due_on < '2026-10-20'
ORDER BY days_overdue DESC;Үр дүн:
name | email | title | due_on | days_overdue
---------+-------------------+--------------------------+------------+-------------
Бат | bat@example.com | Тунгалаг Тамир | 2026-10-04 | 16
Сараа | saraa@example.com | Clean Code | 2026-10-15 | 5
Тэмүүлэн | имэйлгүй | The Pragmatic Programmer | 2026-10-17 | 3Энэ query юу гэж хэлж байна вэ гэвэл: "зээлүүдийг гишүүн ба номтой нийлүүлж, хараахан буцаагаагүй бөгөөд буцаах ёстой огноо нь 10-р сарын 20-ноос өмнө байгаа зээлүүдийн гишүүний нэр, имэйл (байхгүй бол 'имэйлгүй'), номын нэр, буцаах огноо, мөн тайлангийн өдрөөс буцаах огноог хасаж гаргасан хоцролтын хоногийг хоцролтоор ихээс бага руу эрэмбэлж харуул."
Энэ тайлан номын санчид шууд ажлын жагсаалт өгнө: Батад нэн тэргүүнд, утсаар — 16 хоног; Тэмүүлэнд имэйл илгээх боломжгүй тул өөр аргаар холбогдох хэрэгтэй. "имэйлгүй" гэсэн текст NULL-ээс хамаагүй тодорхой мэдээлэл өгч байна — гэвч энэ нь зөвхөн харагдац; өгөгдлийн санд Тэмүүлэнгийн имэйл NULL хэвээр, Бүлэг 2-ын "мэдэхгүй" гэсэн үнэнийг хадгалсаар.
Асуулт: Гишүүн бүрийг зээлийн тоогоор нь ангил: огт зээлээгүй — "Идэвхгүй", нэг зээлтэй — "Эхлэгч", хоёр ба түүнээс олон — "Идэвхтэй". Идэвхгүй гишүүдэд урамшуулал илгээх төлөвлөгөө бий.
Алхам 1 — бүх гишүүн, зээлүүдтэйгээ. "Огт зээлээгүй" гишүүд заавал байх ёстой — Бүлэг 7-ийн LEFT JOIN:
sql
SELECT m.name, l.id
FROM members AS m
LEFT JOIN loans AS l ON l.member_id = m.id;Мессеж: 9 rows returned — найман зээл, нэмэх нь Анугийн тааралгүй мөр.
Алхам 2 — гишүүнээр сагсалж тоолох. Бүлэг 8-ын GROUP BY хичээлийн Жишээ 2: LEFT JOIN-ийн дараа COUNT(*) биш, COUNT(l.id):
sql
SELECT m.name, COUNT(l.id) AS total_loans
FROM members AS m
LEFT JOIN loans AS l ON l.member_id = m.id
GROUP BY m.id, m.name;Таван мөр, Ану 0-тэй.
Алхам 3 — ангиллын шошго. Бүлэг 8-ын сүүлийн хичээлд CASE-ийг SUM дотор ашигласан. CASE нь SELECT-д ч шууд бичигдэж, мөр бүрт утга сонгож болно — энд сагс бүрийн тоог шошго болгоно. CASE олон WHEN-тэй байж болох бөгөөд дээрээс доош шалгаж, эхний үнэн гарсныг сонгоно.
Эцсийн query:
sql
SELECT m.name,
COUNT(l.id) AS total_loans,
CASE
WHEN COUNT(l.id) = 0 THEN 'Идэвхгүй'
WHEN COUNT(l.id) = 1 THEN 'Эхлэгч'
ELSE 'Идэвхтэй'
END AS activity
FROM members AS m
LEFT JOIN loans AS l ON l.member_id = m.id
GROUP BY m.id, m.name
ORDER BY total_loans DESC, m.name;Үр дүн:
name | total_loans | activity
---------+-------------+---------
Бат | 3 | Идэвхтэй
Номин | 2 | Идэвхтэй
Сараа | 2 | Идэвхтэй
Тэмүүлэн | 1 | Эхлэгч
Ану | 0 | ИдэвхгүйЭнэ query юу гэж хэлж байна вэ гэвэл: "бүх гишүүнийг зээлүүдтэй нь (зээлгүйг нь ч хадгалан) нийлүүлж, гишүүнээр сагсалж, гишүүн бүрийн нэр, зээлийн тоо, мөн тоо нь 0 бол 'Идэвхгүй', 1 бол 'Эхлэгч', бусад үед 'Идэвхтэй' гэсэн шошгыг зээлийн тоогоор ихээс бага руу, тэнцвэл нэрээр эрэмбэлж харуул."
Анхаарах нэг зүйл: идэвхийн шошго хүснэгтэд хадгалагдаагүй. Хэрэв members-д “activity” багана нэмж гараар бөглөсөн бол Бүлэг 6-ийн Дулмаагийн тоолуурын нэгэн адил Тэмүүлэн дараагийн номоо зээлэхэд худал болох байсан. Энэ шошго ажиллах бүрдээ одоогийн зээлүүдээс шинээр тооцоологдоно.
Асуулт: Аль номнуудыг хэн ч зээлээгүй вэ? Тэдгээрийг сурталчлах самбарт тавихын тулд нэр, зохиогч, жанр, хувь хэрэгтэй.
Алхам 1 — зээлэгдээгүй номнууд. Бүлэг 9-ийн subquery хичээлийн NOT EXISTS — NULL-аас ангид "байхгүй" шалгалт:
sql
SELECT b.id, b.title
FROM books AS b
WHERE NOT EXISTS (
SELECT 1 FROM loans AS l WHERE l.book_id = b.id
);Гурван мөр: 1, 3, 7.
Алхам 2 — зохиогчдыг нэмэх. Зохиогч холбох гинж — "Монголын нууц товчоо" зохиогчгүй тул Бүлэг 7-ийн дүрмээр гинжийн бүх JOIN LEFT. Олон зохиогчтой ном гарвал Бүлэг 8-ын group_concat нэг нүдэнд нийлүүлнэ. group_concat нь бүх утга NULL бол NULL буцаадаг тул COALESCE-ээр "Тодорхойгүй" болгоно.
Эцсийн query:
sql
SELECT b.title,
COALESCE(group_concat(a.name), 'Тодорхойгүй') AS authors,
b.genre,
b.copies
FROM books AS b
LEFT JOIN book_authors AS ba ON ba.book_id = b.id
LEFT JOIN authors AS a ON ba.author_id = a.id
WHERE NOT EXISTS (
SELECT 1 FROM loans AS l WHERE l.book_id = b.id
)
GROUP BY b.id, b.title, b.genre, b.copies
ORDER BY b.id;Үр дүн:
title | authors | genre | copies
----------------------+------------------+-------------+-------
Монголын нууц товчоо | Тодорхойгүй | Түүх | 2
Учиртай гурван толгой | Д.Нацагдорж | Жүжиг | 1
Clean Architecture | Robert C. Martin | Програмчлал | 1Энэ query юу гэж хэлж байна вэ гэвэл: "номнуудыг зохиогчийн холбоос ба зохиогчидтой (холбоосгүйг нь ч хадгалан) нийлүүлж, ямар ч зээл заадаггүй номнуудыг л үлдээгээд, номоор сагсалж, ном бүрийн нэр, зохиогчдын нэрсийг залгасан жагсаалт (байхгүй бол 'Тодорхойгүй'), жанр, хувийг номын дугаараар эрэмбэлж харуул."
Энэ query нь Түвшин 3-ын гурван бүлгийн хэрэгслийг нэг дор хэрэглэж байна: Бүлэг 7-ийн LEFT JOIN гинж, Бүлэг 8-ын GROUP BY ба group_concat, Бүлэг 9-ийн холбоотой NOT EXISTS. WHERE дахь NOT EXISTS нь зохиогчийн JOIN-уудаас үл хамааран номын түвшинд ажилладаг тул тэдгээрийг хооронд нь саадгүй хослуулж болно. "Монголын нууц товчоо"-г сурталчлах нь сонирхолтой санаа — Монголын хамгийн эртний сонгодог бүтээл хэзээ ч зээлэгдээгүй.
Асуулт: Сар бүр хэдэн зээл гарсан, хэдэн өөр гишүүн зээлсэн, тэр сард зээлсэн номноос хэд нь хоцорч буцаагдсан, хэд нь одоо ч гарт байгаа вэ?
Алхам 1 — сараар сагслах. Бүлэг 8-ын GROUP BY хичээлийн Жишээ 4 — substr()-оор сар гаргах:
sql
SELECT substr(loaned_on, 1, 7) AS month, COUNT(*) AS loans
FROM loans
GROUP BY month;Хоёр мөр: 2026-09 — 5, 2026-10 — 3.
Алхам 2 — бусад тоонуудыг нэмэх. Сагс бүрийн доторх нөхцөлт тоолол — Бүлэг 8-ын сүүлийн хичээлийн гурван арга нэг query-д: COUNT(DISTINCT), COUNT(*) − COUNT(багана), SUM(CASE ...).
Эцсийн query:
sql
SELECT substr(loaned_on, 1, 7) AS month,
COUNT(*) AS loans,
COUNT(DISTINCT member_id) AS borrowers,
SUM(CASE WHEN returned_on > due_on THEN 1 ELSE 0 END) AS late_returns,
COUNT(*) - COUNT(returned_on) AS still_out
FROM loans
GROUP BY month
ORDER BY month;Үр дүн:
month | loans | borrowers | late_returns | still_out
--------+-------+-----------+--------------+----------
2026-09 | 5 | 3 | 1 | 1
2026-10 | 3 | 3 | 0 | 2Энэ query юу гэж хэлж байна вэ гэвэл: "зээлүүдийг зээлсэн сараар нь сагсалж, сар бүрийн зээлийн тоо, давхардалгүй гишүүний тоо, буцаасан огноо нь буцаах ёстой огнооноос хойш байгаа зээлийн тоо, буцаагаагүй зээлийн тоог сараар эрэмбэлж харуул."
9-р сарын сагсыг мөшгье: зээл 1-5. Гишүүд 1, 1, 2, 1, 4 — давхардалгүй гурав. Хоцорсон: зээл 2 (09-30 > 09-24) — нэг. Буцаагаагүй: зээл 4 — нэг. Таван зээл, гурван гишүүн — Бат энэ сард хамгийн идэвхтэй байсан. Энэ query JOIN-гүй тул мөр үржилтийн эрсдэлгүй, нэг хүснэгтээс таван өөр тоо гаргасан.
Асуулт: Нийт зээлийн хэдэн хувь нь жанр бүрт ногдож байна вэ? Энэ нь дараагийн худалдан авалтыг төлөвлөхөд хэрэгтэй.
Алхам 1 — жанр бүрийн зээл. Зээлийг номтой нийлүүлж (жанр номын хүснэгтэд), жанраар сагслах:
sql
SELECT b.genre, COUNT(*) AS loans
FROM loans AS l
INNER JOIN books AS b ON l.book_id = b.id
GROUP BY b.genre;Гурван мөр: Програмчлал 5, Роман 2, Шүлэг 1.
Алхам 2 — нийтээс хувь. Хувь тооцоолохын тулд жанр бүрийн тоог нийт зээлийн тоонд хуваах хэрэгтэй. Нийт тоо бол бүх хүснэгтийн нийлбэр — Бүлэг 9-ийн scalar subquery. Эхний оролдлого:
sql
SELECT b.genre,
COUNT(*) AS loans,
COUNT(*) * 100 / (SELECT COUNT(*) FROM loans) AS share
FROM loans AS l
INNER JOIN books AS b ON l.book_id = b.id
GROUP BY b.genre;Үр дүн:
genre | loans | share
------------+-------+------
Програмчлал | 5 | 62
Роман | 2 | 25
Шүлэг | 1 | 12Хувиудын нийлбэр 99 — нэг хувь хаашаа алга болов? 5 × 100 / 8 нь 62.5 байх ёстой. Энэ бол бүхэл тоон хуваалтын урхи: SQLite-д хоёр бүхэл тоог хуваахад үр дүн нь бүхэл тоо байдаг — бутархай хэсэг алдааны мессежгүйгээр хаягдана. Python-д 5 * 100 // 8 (давхар зураас) бичсэнтэй адил. Засвар нь илэрхийлэлд нэг бутархай тоо оруулах: 100-ийн оронд 100.0. Дараа нь ROUND(утга, 1)-ээр аравны нэг орон хүртэл тоймлоно.
Эцсийн query:
sql
SELECT b.genre,
COUNT(*) AS loans,
ROUND(COUNT(*) * 100.0 / (SELECT COUNT(*) FROM loans), 1) AS share_percent
FROM loans AS l
INNER JOIN books AS b ON l.book_id = b.id
GROUP BY b.genre
ORDER BY loans DESC;Үр дүн:
genre | loans | share_percent
------------+-------+--------------
Програмчлал | 5 | 62.5
Роман | 2 | 25.0
Шүлэг | 1 | 12.5Энэ query юу гэж хэлж байна вэ гэвэл: "зээлүүдийг номтой нийлүүлж, жанраар сагсалж, жанр бүрийн зээлийн тоо, мөн тэр тоог бүх зээлийн тоонд хувааж 100.0-аар үржүүлээд аравны нэг орон хүртэл тоймлосон хувийг зээлийн тоогоор ихээс бага руу эрэмбэлж харуул." Хувиудын нийлбэр одоо 100.0. Зээлийн гуравны хоёр орчим нь програмчлалын номнууд — номын сан тэр жанрт илүү хувь авах нь зүйтэй мэт. Зээлэгдээгүй жанрууд (Жүжиг, Түүх) энд гараагүй нь INNER JOIN-ийн зөв зан: тэд 0% эзэлдэг бөгөөд хэрэв тэднийг ч харуулах шаардлагатай бол books-ээс эхэлж LEFT JOIN хийнэ.
Энд хурдны тухай нэг өгүүлбэр: өмнөх хичээлийн index-ийн дүрмээр library2.db-ийн хүснэгтүүд хэтэрхий жижиг тул эдгээр тайланд index хэрэггүй. Хэрэв номын сан олон жилийн дараа сая зээлтэй болбол loans.member_id болон loans.book_id-д index нэмэх нь эхний алхам болно — бүх таван тайлан тэдгээр баганаар JOIN хийдэг.
Эдгээр таван query бол таны номын сангийн "тайлангийн ном" — эрхлэгч долоо хоног бүр, сар бүр ажиллуулах query-нүүд. Тэдгээрийг нэг файлд цуглуулъя. DB Browser-ийн Execute SQL табд таван эцсийн query-г дараалан буулгаж, query бүрийн өмнө SQL-ийн тайлбар мөрөөр гарчиг бичнэ. SQL-д хоёр зураасаар (--) эхэлсэн мөр нь тайлбар бөгөөд өгөгдлийн сан түүнийг үл тоомсорлодог — Python-ы #-тэй адил:
sql
-- Тайлан 1: хугацаа хэтэрсэн зээлийн сануулгын жагсаалт
-- Тайлангийн өдрийг бодит хэрэглээнд date('now')-оор солино.
SELECT m.name,
...Таван query-г бүгдийг нь ингэж гарчигтайгаар буулгаад, табын дээд талын Save SQL file товчоор Documents\sql-course хавтсанд reports.sql нэрээр хадгална. Query-нүүдийг тус тусад нь ажиллуулахын тулд аль нэгийг нь тодруулж F5 дарна — Бүлэг 1-д сурсан арга. Хэрэв "Хөгжүүлэгчийн хэрэгсэл" сургалтын дадлаа үргэлжлүүлж байгаа бол git add reports.sql болон git commit -m "Add five library report queries" хийнэ. Одоо таны sql-course хавтсанд хоёр баримт бий: library_schema.sql — өгөгдлийн сан ямар бүтэцтэйг, reports.sql — түүнээс юу асуудгийг тэмдэглэсэн.
Эцсийн шалгах цэг: reports.sql таван гарчигтай query агуулна. Тус бүрийг тодруулж ажиллуулахад дээрх таван үр дүнтэй яг таарна.
Хэрэв сонирхож байвал зургаа дахь тайлангаа өөрөө зохиож үзээрэй: "Зохиогч бүрийн номнууд нийт хэдэн удаа зээлэгдсэн, хэдэн өөр гишүүн тэдгээрийг уншсан бэ?" Энэ нь authors-ээс эхэлж, book_authors, books, loans-ийг LEFT JOIN-оор нийлүүлэх, давхардалгүй тоолох шаардлагатай — Бүлэг 7-ийн мөр үржилт, Бүлэг 8-ын COUNT(DISTINCT)-ийг санаарай. Номгүй Al Sweigart 0, 0 гэсэн мөртэй гарах ёстой. Энэ хичээлийн дадлаар — алхам бүрд мөрийн тоог шалгаж — угсраад, reports.sql-д нэмж болно. Эдгээр нь зөвхөн санал бөгөөд дараагийн хичээлүүд тэдгээрийг хийсэн гэж тооцохгүй.
Бүхэл тоон хуваалт. Тайлан 5-ын эхний оролдлогод харсанчлан COUNT(*) * 100 / ... нь бутархайг чимээгүй хаядаг. Хувь, дундаж гэх мэт бутархай хариу хүлээж буй хуваалт бүрт илэрхийлэлд 100.0 эсвэл 1.0 гэх мэт бутархай тоо оруулаарай. PostgreSQL-д ч бүхэл тоон хуваалт мөн адил ажилладаг.
julianday-ийн үр дүнг CAST хийхгүй байх. julianday(...) - julianday(...) нь 16.0 гэх мэт бутархай тоо буцаадаг. Хэрэв огноонд цаг ч агуулагдсан бол 15.625 гэх мэт хагас хоног гарна. Бүтэн хоног хүсвэл CAST(... AS INTEGER) бичнэ — тэр нь бутархай хэсгийг тасалдаг. Мөн julianday-д YYYY-MM-DD бус хэлбэрийн огноо өгвөл NULL буцаана — Бүлэг 3-ын огнооны дүрэм энд ч хүчинтэй.
CASE-ийн WHEN-уудын дараалал. Тайлан 2-т WHEN COUNT(l.id) >= 1 THEN 'Эхлэгч'-ийг эхэнд бичвэл Бат, Номин, Сараа бүгд "Эхлэгч" болно — CASE эхний үнэн WHEN-ийг сонгоод зогсдог. Нөхцлүүдийг нарийнаас өргөн рүү, эсвэл бие биентэйгээ давхцахгүйгээр бичээрэй.
Тайлбар мөрийг query-ний дунд таслах. -- нь мөрийн төгсгөл хүртэлх бүх зүйлийг тайлбар болгодог. Хэрэв нэг мөрөнд SELECT name -- нэр, email гэж бичвэл email ч тайлбар болж, query өөр үр дүн өгнө. Тайлбарыг тусдаа мөрөнд, эсвэл query-ний мөрийн хамгийн төгсгөлд бичээрэй.
Тайлангийн өдрийг кодонд мартаж үлдээх. '2026-10-20' гэсэн тогтмол огноо хичээлд тохиромжтой, гэвч бодит хэрэглээнд үүнийг date('now')-оор солихоо мартвал тайлан үргэлж 10-р сарын 20-ны байдлаар хариулж, хэн ч анзаарахгүй. reports.sql-д тайлбар мөр нэмсэн нь яг энэ шалтгаантай.
Энэ дасгалд та номын сангийн таван бодит тайланг Түвшин 3-ын хэрэгслүүдээр алхам алхмаар бүтээлээ. Хугацаа хэтэрсэн зээлийн жагсаалтад гурван хүснэгтийн JOIN, julianday()-оор хоногийн зөрүү, COALESCE-ээр NULL-ийн уншигдахуйц харагдацыг ашиглав. Идэвхийн ангилалд LEFT JOIN, GROUP BY, COUNT(l.id), олон WHEN-тэй CASE-ийг хослуулав. Зээлэгдээгүй номнуудын жагсаалтад NOT EXISTS, LEFT JOIN гинж, group_concat нэг query-д ажилласан. Сарын тайланд нэг хүснэгтээс таван өөр тоог илэрхийллээр сагсалж гаргав. Жанрын хувийн тайланд scalar subquery болон бүхэл тоон хуваалтын урхийг 100.0-аар засав. Тайлан бүрийг FROM-оос эхлэн, алхам бүрд мөрийн тоог шалгаж угсарч, таван query-г тайлбартайгаар reports.sql-д хадгалж Git-д оруулсан.
Ингээд Түвшин 3 — "Хүчирхэг query" — бүрэн дууслаа. Сургалтын эхэнд "миний код ажилладаг, гэхдээ доор нь юу болдгийг би мэдэхгүй" гэсэн мэдрэмжийн тухай ярьсан. Одоо та тэр "доор нь" болдог зүйлийг уншиж, зохиож, хүссэн асуултаа асууж чаддаг болсон. Гэвч бүх ажлаа бид нэг файлд амьдардаг хувийн дэвтэр болох SQLite дээр хийсэн. Түвшин 4-т бид архивын алба руу — PostgreSQL руу шилжинэ. Бүлэг 10 server өгөгдлийн сан гэж юу вэ, яагаад хэрэгтэйг тайлбарлаж, түүнийг компьютертээ суулгаж, таны мэдэх SQL-ийг тэнд ажиллуулахаас эхэлнэ.
Бүртгэлтэй болсноор энэ сургалтын бүх хичээлд хандах эрх авна.