Ачааллж байна...
Өмнөх хичээлд бид SELECT * FROM books; болон SELECT title, author FROM books; гэх мэт анхны query-нүүдээ бичсэн. Тэдгээр нь SELECT, FROM гэсэн хоёр хэсгээс бүтсэн богино өгүүлбэрүүд байсан. Гэвч бодит ажилд query-нүүд илүү урт болдог: мөрийг шүүх, эрэмбэлэх, тоолох, хязгаарлах зэрэг олон хэсэг нэмэгддэг. Тэдгээр хэсэг бүхэн query дотор тогтсон байрандаа л ирэх ёстой бөгөөд байраа сольвол SQLite таныг ойлгохгүй.
Энэ хичээлд бид SELECT query-ний араг ясыг бүхэлд нь харна. Хэсэг бүрийг clause гэж нэрлэдэг — монголоор "өгүүлбэрийн хэсэг" гэж ойлгож болно. Бид одоохондоо зөвхөн SELECT, FROM хоёрыг сайн мэдэх ба бусад clause-уудыг зөвхөн урьдчилан харж, тэдгээр нь араг ясны аль хэсэгт байрлахыг таних болно. Дараагийн бүлгүүдэд clause бүрийг нэг бүрчлэн гүнзгий судлах тул энэ хичээл тэдгээрийн байрыг тогтоох газрын зураг юм.
Мөн өмнөх хичээлийн төгсгөлд нэг хачин зан гэж хэлсэн алдааг энд тайлбарлана: FROM-ийг мартах эсвэл таслал дутуу бичихэд яг юу болдог вэ. Энэ нь SELECT-ийн бүтцийг ойлгосны дараа л утга учиртай болдог.
Албан байгууллагын өргөдлийн маягтыг төсөөлөөд үзээрэй. Маягт дээр нүднүүд тогтсон дарааллаар байрладаг: эхлээд овог нэр, дараа нь регистрийн дугаар, дараа нь хаяг, хамгийн сүүлд гарын үсэг. Зарим нүд заавал бөглөх, зарим нь сонголттой байдаг. Сонголттой нүдийг хоосон орхиж болно, гэхдээ гарын үсгийг маягтын эхэнд, овог нэрийг төгсгөлд нь бичиж болохгүй — тэгвэл ажилтан маягтыг хүлээж авахгүй.
SELECT query яг ийм маягт юм. Нүднүүд нь SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT гэсэн тогтсон дараалалтай. Ихэнх нүд сонголттой — та зөвхөн хэрэгтэйгээ бөглөнө. Гэхдээ бөглөсөн нүднүүд нь заавал маягтын дарааллаараа байх ёстой. SQLite бол маягтыг хүлээн авдаг ажилтан бөгөөд дараалал зөрчсөн маягтыг “syntax error” гэсэн тайлбартай буцааж өгдөг.
SELECT query-ний бүрэн араг яс ийм харагдана:
sql
SELECT багануудын жагсаалт
FROM хүснэгтийн нэр
WHERE мөрийг шүүх нөхцөл
GROUP BY бүлэглэх багана
HAVING бүлгийг шүүх нөхцөл
ORDER BY эрэмбэлэх багана
LIMIT хэдэн мөр авах;Энэ бол ажиллах query биш, харин дарааллын зураг гэдгийг анхаараарай — монгол үгс нь зөвхөн тайлбар. Мөр бүр нэг clause бөгөөд тэдгээрийн дараалал хэзээ ч өөрчлөгддөггүй. SELECT нь ямар баганыг харуулахыг, FROM нь ямар хүснэгтээс уншихыг, WHERE нь ямар мөрүүдийг үлдээхийг, GROUP BY болон HAVING нь мөрүүдийг сагслан бүлэглэж тэдгээрийг шүүхийг, ORDER BY нь үр дүнг ямар дарааллаар байрлуулахыг, LIMIT нь хэдэн мөрөөр хязгаарлахыг шийддэг.
Эдгээрийн аль нь хэзээ ирэхийг товч тэмдэглэе. SELECT, FROM хоёрыг та өмнөх хичээлд сурсан. WHERE, ORDER BY, LIMIT гурвыг дараагийн бүлэгт (Бүлэг 2) сурна. GROUP BY, HAVING хоёрыг Бүлэг 8-д тоо баримт нэгтгэх үед сурна. Тиймээс энэ араг ясыг сургалтын эхний хагасын замын зураг гэж харж болно — бид дээрээс доош нь нэг нэгээр нь нүдийг бөглөж сурах болно.
Нэг clause-ийг хоосон орхих нь маш энгийн: зүгээр л тэр мөрийг бичихгүй. Өмнөх хичээлийн SELECT title FROM books; нь эхний хоёр нүдийг бөглөж, бусад тавыг хоосон орхисон query байсан. Хоосон орхисон нүд бүр "энэ талаар тусгай хүсэлт алга" гэсэн утгатай: WHERE байхгүй бол бүх мөр үлдэнэ, ORDER BY байхгүй бол дараалал баталгаагүй, LIMIT байхгүй бол бүх мөр ирнэ.
Араг яс бодит query дээр хэрхэн ажилладгийг харахын тулд WHERE, ORDER BY, LIMIT гурвыг нэг удаа хамтад нь ашиглая. Тэдгээрийн дэлгэрэнгүйг одоо тайлбарлахгүй — зөвхөн тэдгээр нь араг ясны байрандаа хэрхэн сууж байгааг анзаараарай. books хүснэгт өмнөх хичээлийнхтэй адил байгаа:
id | title | author | year | genre | copies
---+--------------------------+------------------+------+-------------+-------
1 | Монголын нууц товчоо | NULL | 1240 | Түүх | 2
2 | Тунгалаг Тамир | Ч.Лодойдамба | 1962 | Роман | 3
3 | Учиртай гурван толгой | Д.Нацагдорж | 1934 | Жүжиг | 1
4 | Clean Code | Robert C. Martin | 2008 | Програмчлал | 4
5 | Python Crash Course | Eric Matthes | 2015 | Програмчлал | 5
6 | The Pragmatic Programmer | Andrew Hunt | 1999 | Програмчлал | 2Query:
sql
SELECT title, year
FROM books
WHERE year > 1950
ORDER BY year
LIMIT 3;Үр дүн:
title | year
-------------------------+-----
Тунгалаг Тамир | 1962
The Pragmatic Programmer | 1999
Clean Code | 2008Энэ query юу гэж хэлж байна вэ гэвэл: “books хүснэгтээс year нь 1950-аас их мөрүүдийг аваад, тэдгээрийг он өсөх дарааллаар эрэмбэлээд, эхний гурвынх нь title болон year-ийг харуул.” Өөрөөр хэлбэл: 1950 оноос хойш хэвлэгдсэн номнуудаас хамгийн эртний гурвыг нь.
Одоо мөр бүрийн хувь заяаг мөшгье. WHERE нь "Монголын нууц товчоо" (1240) болон "Учиртай гурван толгой" (1934) хоёрыг хассан, учир нь тэдгээрийн он 1950-аас бага. Үлдсэн дөрвөн мөрийг ORDER BY он өсөх дарааллаар нь байрлуулсан: 1962, 1999, 2008, 2015. Дараа нь LIMIT эхний гурвыг нь авч, “Python Crash Course” (2015)-ийг хассан. Хамгийн сүүлд SELECT мөр бүрээс зөвхөн title болон year баганыг үлдээсэн. Query-г таван мөрөнд хувааж бичсэн нь clause бүрийг араг ясны мөр бүртэй шууд тааруулж харах боломж олгож байгааг анзаараарай — энэ бол урт query бичих сайн дадал юм.
Дээрх мөшгилтөд нэг сонирхолтой зүйл байсан: бид мөрүүдийн хувь заяаг SELECT-ээс эхэлж биш, харин FROM-оос эхэлж тайлбарласан. Учир нь өгөгдлийн сан query-г бичсэн дарааллаар нь гүйцэтгэдэггүй. Логикийн хувьд эхлээд FROM (аль хүснэгт), дараа нь WHERE (аль мөрүүд), дараа нь SELECT (аль баганууд), дараа нь ORDER BY (ямар дарааллаар), хамгийн сүүлд LIMIT (хэдийг) ажилладаг. Бодит өгөгдлийн сан дотроо илүү ухаалаг арга хэрэглэж болох ч үр дүн нь яг энэ логик дараалалд нийцдэг.
Энд монгол хэлний нэг давуу тал илэрдэг. Англи хэлэнд үйл үг эхэнд ирдэг тул SQL “SELECT ... FROM ...” гэж эхэлдэг. Харин монгол хэлэнд үйл үг өгүүлбэрийн төгсгөлд ирдэг тул бид query-г чангаар уншихдаа байгалиараа “books хүснэгтээс ... мөрүүдийг аваад ... харуул” гэж FROM-оос эхэлж, SELECT-ээр төгсгөдөг. Өөрөөр хэлбэл монголоор унших нь query-ний гүйцэтгэх дараалалтай ойролцоо байдаг. Энэ бол чангаар унших дадал тань зүгээр нэг зуршил биш, харин SQL-ийг зөв бодох хэрэгсэл болдгийн нэг шалтгаан юм.
Энэ ялгааг одоо цээжлэх шаардлагагүй. Гэхдээ цаашид нэг нөхцөлд энэ нь маш чухал болно: Бүлэг 8-д WHERE болон HAVING хоёрын ялгааг судлахдаа "аль нь түрүүлж ажилладаг вэ" гэдэг асуулт бүх зүйлийг тайлбарлах түлхүүр болно. Тэр үед энэ хичээлийн гүйцэтгэх дарааллыг санаж байвал хангалттай.
Жишээ 1: FROM-гүй SELECT
Араг ясны бараг бүх нүд сонголттой гэж хэлсэн. Тэгвэл FROM ч мөн сонголттой юу? SQLite-д тийм. Хүснэгтгүй query бичиж болно:
sql
SELECT 2 + 3;Үр дүн:
2 + 3
-----
5Энэ query юу гэж хэлж байна вэ гэвэл: “2 нэмэх 3-ын утгыг харуул.” Энд ямар ч хүснэгтээс уншаагүй, зөвхөн илэрхийллийг тооцоолоод нэг мөр, нэг багана бүхий үр дүн буцаасан. Баганын нэр нь бидний бичсэн илэрхийлэл өөрөө болсныг анзаараарай. Энэ жишээ нь SELECT-ийн жинхэнэ утгыг харуулж байна: SELECT бол "энэ утгуудыг харуул" гэсэн тушаал бөгөөд FROM нь тэр утгууд хаанаас ирэхийг заадаг нэмэлт юм. Багана гэдэг нь хүснэгтээс ирдэг утга, 2 + 3 нь тооцоолсон утга — SELECT хоёуланг нь харуулж чадна.
Энэ нь өмнөх хичээлийн нэг хачин үзэгдлийг тайлбарлана. Хэрэв та SELECT title; гэж FROM-гүй бичвэл SQLite no such column: title гэсэн алдаа өгнө. Энэ мессеж юу гэж хэлж байна вэ гэвэл: “title гэдэг нэртэй багана байхгүй байна.” Гэвч books хүснэгтэд title багана байгаа шүү дээ? Асуудал нь FROM-гүй query-д SQLite ямар ч хүснэгт рүү хардаггүй — 2 + 3 шиг тооцоолох гэж оролдоод, title гэдэг үгийг юу гэж ойлгохоо мэдэхгүй болдог. Тиймээс энэ алдааг харвал "багана байхгүй" гэхээсээ илүү “FROM байгаа юу, зөв хүснэгтийг заасан уу” гэдгийг эхлээд шалгаарай.
Жишээ 2: таслал дутуу — алдаагүй буруу
Одоо өмнөх хичээлд анхааруулсан хамгийн аюултай алдааг харъя. Бид title болон author хоёрыг сонгох гэж байгаад таслалаа мартжээ:
sql
SELECT title author FROM books;Үр дүн:
author
------------------------
Монголын нууц товчоо
Тунгалаг Тамир
Учиртай гурван толгой
Clean Code
Python Crash Course
The Pragmatic ProgrammerЯмар ч алдааны мессеж гараагүй. Гэвч үр дүнг сайн хараарай: зөвхөн нэг багана ирсэн, түүний толгой нь “author” гэж бичигдсэн мөртлөө доторх утгууд нь номын нэрс байна. Энэ query-г SQLite-ийн нүдээр уншвал: “books хүснэгтээс title баганыг сонгоод, үр дүнд түүнийг author гэж нэрлэ.” SQL-д баганын нэрийн араас шууд өөр үг бичвэл тэр үг нь баганын шинэ нэр (alias) гэж ойлгогддог. Энэ бол хууль ёсны, хэрэгтэй боломж бөгөөд бид түүнийг Бүлэг 7-д олон хүснэгт холбох үед байнга ашиглана. Гэхдээ таслал мартсан үед энэ боломж таныг хуурдаг.
Энэ жишээ нь бүх сургалтын турш хэрэгтэй нэг дадлыг заана: query алдаагүй ажилласан ч үр дүнг заавал нүдээрээ шалга. Хэдэн багана ирсэн, баганын нэрс таны хүссэнтэй таарч байна уу, утгууд нь баганын нэртэйгээ нийцэж байна уу. Алдааны мессеж бол SQLite танд туслах гэж оролдож буй дохио юм; харин алдаагүй буруу үр дүн бол хэн ч дохио өгөхгүй тохиолдол. Бүлэг 3-т UPDATE тушаалын тухай ярихдаа яг ийм "алдаагүй гамшиг"-ийн хамгийн аймшигтай хэлбэрийг харах болно.
Жишээ 3: clause-ийн дараалал зөрчих
Одоо маягтын нүднүүдийг санаатайгаар буруу байранд бичье. ORDER BY-ийг WHERE-ийн өмнө тавьсан query:
sql
SELECT title, year
FROM books
ORDER BY year
WHERE year > 1950;Үр дүн: query ажиллахгүй бөгөөд мессежийн талбарт ийм алдаа гарна:
near "WHERE": syntax errorЭнэ мессеж юу гэж хэлж байна вэ гэвэл: “WHERE гэдэг үгийн ойролцоо SQL-ийн дүрэм зөрчигдсөн байна.” SQLite query-г дээрээс доош уншиж явахдаа ORDER BY-д хүрээд "одоо араг ясны ORDER BY нүд рүү орлоо, үүний араас зөвхөн LIMIT ирж болно" гэж хүлээдэг. Гэтэл WHERE ирсэн — энэ нь араг ясанд ORDER BY-ийн өмнө байх ёстой нүд. SQLite буцаж очих аргагүй тул яг тэр үг дээр зогсож алдаа өгсөн. Засах арга нь WHERE мөрийг ORDER BY-ийн өмнө шилжүүлэх бөгөөд тэгэхэд query дээрх Анхны жишээтэй адил ажиллана.
Ижил алдааг өөр хэлбэрээр ч харж болно. Хэрэв FROM books SELECT title; гэж FROM-оор эхлүүлбэл near "FROM": syntax error гэсэн алдаа гарна. SQLite query-ний эхний үгийг харж ямар төрлийн тушаал болохыг шийддэг бөгөөд FROM-оор эхэлдэг тушаал SQL-д байхгүй. Хэдийгээр монгол хэлэнд бид “books хүснэгтээс” гэж эхэлж уншдаг ч бичихдээ SQL-ийн маягтын дарааллыг дагах ёстой. Энэ хоёрыг хольж болохгүй: унших нь бодох хэрэгсэл, бичих нь дүрэм.
Хэрэв сонирхож байвал Анхны жишээний query-ээс нэг clause-ийг нэг нэгээр нь хасаж үзээрэй. LIMIT-ийг хасвал хэдэн мөр ирэх вэ? ORDER BY-ийг хасвал мөрийн дараалал юу болох вэ? WHERE-ийг хасвал ямар номнууд нэмэгдэх вэ? Ажиллуулахаасаа өмнө үр дүнг таамаглаж, query-г монголоор чангаар уншаад, дараа нь таамаглалаа шалгаарай. Мөн SELECT 10 * 12; гэх мэт хүснэгтгүй тооцоолол хийж үзэж болно. Эдгээр нь зөвхөн санал бөгөөд дараагийн хичээлүүд тэдгээрийг хийсэн гэж тооцохгүй.
Clause-уудын дараалал зөрчих. Дээрх Жишээ 3-т харсанчлан ORDER BY-ийг WHERE-ийн өмнө, эсвэл LIMIT-ийг ORDER BY-ийн өмнө бичвэл near "...": syntax error гэсэн алдаа гарна. Хашилтан дотор гарч ирэх үг нь ихэвчлэн буруу байранд орсон clause-ийн эхний үг байдаг. Засах арга нь араг ясны дарааллыг (SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT) санаж, тэр clause-ийг зөв байранд нь шилжүүлэх юм. Эхэн үедээ араг ясыг цаасан дээр бичээд компьютерийнхээ хажууд тавьж болно — хэдэн долоо хоногийн дараа танд хэрэггүй болно.
Таслал мартсанаас баганын нэр солигдох. Жишээ 2-т харсанчлан SELECT title author FROM books; нь алдаагүй ажиллаж, нэг багана буцаадаг. Энэ тохиолдолд алдааны мессеж байхгүй тул үр дүнгийн баганын тоог тоолох нь цорын ганц хамгаалалт юм. Хэрэв та гурван багана хүссэн атлаа хоёр ирсэн бол баганын жагсаалтдаа таслал бүрийг шалгаарай.
Хоёр query-г цэг таслалгүй бичих. Бичих талбарт хоёр query зэрэг байхад эхнийх нь цэг таслалгүй бол SQLite тэр хоёрыг нэг урт query гэж ойлгоно. Жишээ нь SELECT title FROM books гэсэн мөрийн араас SELECT name FROM members; бичвэл near "SELECT": syntax error гарна. Утга нь "хоёр дахь SELECT гэдэг үгийн ойролцоо дүрэм зөрчигдлөө" — SQLite эхний query-ний араас араг ясны дараагийн нүдийг хүлээж байтал шинэ SELECT ирсэн. Query бүрийг цэг таслалаар төгсгөх дадал нь энэ асуудлаас бүрэн хамгаална.
FROM мартсанаас “no such column”. Жишээ 1-д тайлбарласанчлан хүснэгтэд байдаг баганыг FROM-гүй query-д нэрлэвэл no such column алдаа гарна. Энэ мессеж танд худал хэлж байгаа юм шиг санагдаж болно, учир нь багана үнэхээр байгаа. Үнэндээ мессеж үнэн: тэр query-ний хүрээнд ямар ч хүснэгт заагаагүй тул багана "байхгүй" юм. Ийм алдааг харвал эхлээд FROM-оо шалгаарай.
Энэ хичээлд та SELECT query-ний араг ясыг бүхэлд нь харлаа: SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT гэсэн тогтсон дараалал. Хэрэгтэй clause-аа л бичиж, бусдыг хоосон орхиж болох ч бичсэн clause-ууд заавал энэ дарааллаар байх ёстой, эс бөгөөс syntax error гарна. Өгөгдлийн сан query-г бичсэн дарааллаар биш, харин FROM, WHERE, SELECT, ORDER BY, LIMIT гэсэн логик дарааллаар гүйцэтгэдэг бөгөөд монгол хэлээр унших нь энэ дараалалтай байгалиараа нийцдэг. Мөн таслал мартахад баганын нэр солигдох "алдаагүй буруу" үр дүнг харж, query бүрийн үр дүнг нүдээр шалгах дадлын ач холбогдлыг ойлголоо.
Ингээд Бүлэг 1 дууслаа. Та SQL ямар хэрэгтэй, хаана нуугдаж байсныг мэдэж, хэрэгслээ суулгаж, анхны query-нүүдээ бичиж, тэдгээрийн бүтцийг ойлголоо. Дараагийн бүлэгт бид араг ясны WHERE нүдийг бөглөж эхэлнэ. Мөрүүдийг харьцуулалт болон AND, OR, NOT ашиглан шүүж сурах бөгөөд Python-ы анхан шатны сургалтад сурсан логик тань SQL дотор дахин төрөх болно.
Бүртгэлтэй болсноор энэ сургалтын бүх хичээлд хандах эрх авна.