Ачааллж байна...
Бүлэг 1-д бид SELECT ашиглан хүснэгтээс ямар баганыг харахыг сонгож сурсан. Гэвч тэр бүх query-нүүд хүснэгтийн бүх мөрийг буцааж байсан. Манай books хүснэгт зургаахан номтой тул энэ нь асуудал биш, харин бодит номын сан мянга мянган номтой байдаг. Тэдгээрийг бүгдийг нь харах шаардлага бараг гардаггүй — бидэнд ихэвчлэн "програмчлалын номнууд", “2000 оноос хойш гарсан номнууд”, "Дарханд амьдардаг гишүүд" гэх мэт тодорхой нөхцөлд таарах мөрүүд хэрэгтэй.
Энэ хичээлд бид араг ясны WHERE нүдийг бөглөж сурна. WHERE нь мөр бүрийг нэг нөхцөлөөр шалгаж, нөхцөл үнэн бол мөрийг үлдээж, худал бол хасдаг. Бид харьцуулах тэмдгүүдийг (их, бага, тэнцүү, тэнцүү биш), дараа нь AND, OR, NOT гэсэн гурван логик үгийг ашиглан олон нөхцөлийг нэгтгэж сурна. Хамгийн сүүлд хаалт (()) яагаад чухал болохыг жинхэнэ буруу үр дүнгээр харуулна.
Энд нэг баяртай мэдээ бий. Хэрэв та Python-ы анхан шатны сургалтыг дүүргэсэн бол энэ хичээлийн логикийн хэсгийг та аль хэдийн мэднэ. Python-ы if нөхцөлд ашигладаг and, or, not нь SQL-д бараг яг ижил утгатайгаар дахин төрдөг. Ялгаа нь цөөн бөгөөд тэдгээрийг замдаа нэг бүрчлэн тэмдэглэнэ.
WHERE-ийг номын сангийн хаалган дээрх харуултай зүйрлэж болно. Хүснэгтийн мөр бүр нэг нэгээрээ харуулын өмнө ирж зогсдог. Харуулын гарт нэг дүрэм бий, жишээ нь "зөвхөн 2000 оноос хойш хэвлэгдсэн номыг нэвтрүүл." Харуул ном бүрийн оныг харж, дүрэмд таарвал нэвтрүүлж, таарахгүй бол буцаана. Хаалганы цаана гарч ирсэн номнууд л үр дүнд орно.
Энэ зүйрлэлээс хоёр чухал зүйл гарна. Нэгдүгээрт, харуул мөр бүрийг тусад нь, бусдаас үл хамааран шалгадаг — нэг номын шийдвэр нөгөө номын шийдвэрт нөлөөлдөггүй. Хоёрдугаарт, харуул хүснэгтийг өөрчилдөггүй: буцаагдсан номнууд устахгүй, зүгээр л энэ query-ний үр дүнд ороогүй. Дараагийн query-д тэд дахин хаалган дээр ирж, өөр дүрмээр шалгагдана.
Бидний ажиллах 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 > 2000;Үр дүн:
title | year
--------------------+-----
Clean Code | 2008
Python Crash Course | 2015Энэ query юу гэж хэлж байна вэ гэвэл: “books хүснэгтээс year нь 2000-аас их мөрүүдийг аваад, тэдгээрийн title болон year-ийг харуул.” Одоо харуулын ажлыг мөр бүрээр мөшгье. 1-р мөр: 1240 > 2000 юу? Үгүй, хасагдлаа. 2-р мөр: 1962 > 2000? Үгүй. 3-р мөр: 1934? Үгүй. 4-р мөр: 2008 > 2000? Тийм, үлдлээ. 5-р мөр: 2015? Тийм, үлдлээ. 6-р мөр: 1999 > 2000? Үгүй — 1999 нь 2000-д маш ойрхон боловч бага хэвээр.
WHERE-ийн дараах year > 2000 хэсгийг нөхцөл (condition) гэж нэрлэдэг. Нөхцөл бүр мөр болгон дээр үнэн эсвэл худал гэсэн хариу өгдөг бөгөөд WHERE зөвхөн үнэн гарсан мөрүүдийг үлдээдэг. Энэ нь Python-ы if year > 2000: гэсэн мөртэй утгын хувьд яг ижил — ялгаа нь Python-д бид нэг утгыг шалгадаг бол SQL-д нэг нөхцөл бүх мөр дээр автоматаар давтагддаг. Өөрөөр хэлбэл WHERE дотор for давталт нуугдаж байгаа бөгөөд та түүнийг бичих шаардлагагүй.
Мөн хоёр ажиглалт хийе. Бид SELECT-д year баганыг сонгосон ч WHERE-д ашиглах баганыг заавал SELECT-д бичих шаардлагагүй. SELECT title FROM books WHERE year > 2000; гэж бичсэн ч яг ижил хоёр ном ирэх бөгөөд зөвхөн оны багана үр дүнд харагдахгүй. Харуул номын оныг харж шийдвэр гаргаж болох ч та оныг нь хуулж авах албагүй. Нэгэнт өмнөх хичээлд гүйцэтгэх дарааллыг харсан тул шалтгаан нь ойлгомжтой: WHERE нь SELECT-ээс өмнө ажилладаг тул хүснэгтийн бүх баганыг хардаг.
SQL-д зургаан харьцуулах тэмдэг бий:
= тэнцүү
<> тэнцүү биш (мөн != гэж бичиж болно)
< бага
> их
<= бага буюу тэнцүү
>= их буюу тэнцүүЭдгээрийн ихэнх нь Python-тай ижил, гэхдээ нэг чухал ялгаа бий. Python-д тэнцүү эсэхийг == (хоёр тэнцүүгийн тэмдэг) гэж шалгадаг, учир нь ганц = нь хувьсагчид утга оноох үйлдэл байдаг. SQL-ийн WHERE дотор утга оноох үйлдэл байдаггүй тул тэнцүү эсэхийг ганц =-ээр шалгадаг. SQLite хоёр тэнцүүг ч хүлээн авдаг ч энэ нь стандарт биш бөгөөд PostgreSQL дээр ажиллахгүй. Тиймээс эхнээсээ ганц = бичих дадал гаргаарай. Тэнцүү биш гэдгийг SQL-ийн стандартаар <> гэж бичдэг; Python-тай адил != ч ажилладаг ч энэ сургалтад бид <>-ийг ашиглана.
Жишээ 1: текстийг тэнцүүгээр шүүх
Тоо харьцуулахаас гадна текстийг ч шалгаж болно. Програмчлалын номнуудыг олъё. Хүснэгт дээрхтэй адил. Query:
sql
SELECT title, genre
FROM books
WHERE genre = 'Програмчлал';Үр дүн:
title | genre
-------------------------+------------
Clean Code | Програмчлал
Python Crash Course | Програмчлал
The Pragmatic Programmer | ПрограмчлалЭнэ query юу гэж хэлж байна вэ гэвэл: “books хүснэгтээс genre нь яг 'Програмчлал' гэсэн мөрүүдийн title болон genre-ийг харуул.” Текстийн утгыг дан хашилтаар ('...') хүрээлдэгийг анзаараарай. Энэ нь SQL-ийн заавал мөрдөх дүрэм: дан хашилт доторх зүйл нь утга, хашилтгүй үг нь баганын эсвэл хүснэгтийн нэр гэж ойлгогддог. Хашилтаа мартвал юу болохыг доор Түгээмэл алдаанууд хэсэгт харна.
Мөн текстийн харьцуулалт үсэг бүрээр, яг таг явагддаг. 'Програмчлал' болон 'програмчлал' хоёр SQLite-ийн хувьд өөр утга тул жижиг үсгээр эхлүүлж бичвэл нэг ч мөр ирэхгүй, алдааны мессеж ч гарахгүй. Хоосон үр дүн гарвал эхлээд текстээ хүснэгтэд байгаатай үсэг бүрээр нь харьцуулаарай.
Жишээ 2: тэнцүү биш
Одоо members хүснэгт рүү шилжье:
id | name | city | joined_year | email
---+----------+-------------+-------------+------------------
1 | Бат | Улаанбаатар | 2023 | bat@example.com
2 | Сараа | Дархан | 2024 | saraa@example.com
3 | Тэмүүлэн | Улаанбаатар | 2022 | NULL
4 | Номин | Эрдэнэт | 2024 | nomin@example.com
5 | Ану | Улаанбаатар | 2025 | anu@example.comУлаанбаатараас бусад хотод амьдардаг гишүүдийг олъё. Query:
sql
SELECT name, city
FROM members
WHERE city <> 'Улаанбаатар';Үр дүн:
name | city
------+--------
Сараа | Дархан
Номин | ЭрдэнэтЭнэ query юу гэж хэлж байна вэ гэвэл: “members хүснэгтээс city нь 'Улаанбаатар' биш мөрүүдийн name болон city-г харуул.” Харуул таван гишүүнийг шалгахад Бат, Тэмүүлэн, Ану гурвын хот 'Улаанбаатар'-тай тэнцүү тул тэд хасагдсан, харин Сараа болон Номин хоёрынх өөр тул үлдсэн. Энэ төрлийн query нь "хэн нь ... биш вэ" гэсэн асуултад хариулахад их хэрэглэгддэг.
Жишээ 3: AND — хоёр нөхцөл хоёулаа үнэн байх
Олон гишүүн нэгэн зэрэг уншиж болохуйц, буюу 3 болон түүнээс дээш хувьтай програмчлалын номнуудыг олъё. Энд хоёр нөхцөл хэрэгтэй: жанр нь програмчлал байх, мөн хувийн тоо нь 3-аас багагүй байх. Query:
sql
SELECT title, genre, copies
FROM books
WHERE genre = 'Програмчлал' AND copies >= 3;Үр дүн:
title | genre | copies
--------------------+-------------+-------
Clean Code | Програмчлал | 4
Python Crash Course | Програмчлал | 5Энэ query юу гэж хэлж байна вэ гэвэл: “books хүснэгтээс genre нь 'Програмчлал' бөгөөд copies нь 3 буюу түүнээс их мөрүүдийг харуул.” AND нь "бөгөөд", "мөн" гэсэн утгатай бөгөөд хоёр талын нөхцөл хоёулаа үнэн байж л мөр үлдэнэ. Мөшгье: “Clean Code” — програмчлал мөн, 4 хувь, хоёулаа үнэн, үлдлээ. “Python Crash Course” — програмчлал, 5 хувь, үлдлээ. “The Pragmatic Programmer” — програмчлал мөн боловч ердөө 2 хувь, хоёр дахь нөхцөл худал тул хасагдлаа. "Тунгалаг Тамир" нь 3 хувьтай ч жанр нь роман тул эхний нөхцөл худал, хасагдлаа.
Энэ нь Python-ы анхан шатны сургалтад сурсан if genre == "Програмчлал" and copies >= 3: нөхцөлтэй утгын хувьд яг ижил. Ялгаа нь зөвхөн бичлэгт: SQL-д and биш AND (том үсгээр бичих нь бидний уламжлал), == биш =, текст давхар биш дан хашилтанд. Логик нь өөрөө огт өөрчлөгдөөгүй — та энэ хэсгийг аль хэдийн мэдэж байсан.
Жишээ 4: OR — дор хаяж нэг нь үнэн байх
Уран зохиолын номнууд, буюу роман эсвэл жүжгийг олъё. Query:
sql
SELECT title, genre
FROM books
WHERE genre = 'Роман' OR genre = 'Жүжиг';Үр дүн:
title | genre
----------------------+------
Тунгалаг Тамир | Роман
Учиртай гурван толгой | ЖүжигЭнэ query юу гэж хэлж байна вэ гэвэл: “books хүснэгтээс genre нь 'Роман' эсвэл 'Жүжиг' байгаа мөрүүдийг харуул.” OR нь "эсвэл" гэсэн утгатай бөгөөд хоёр нөхцлийн аль нэг нь (эсвэл хоёулаа) үнэн бол мөр үлдэнэ. "Тунгалаг Тамир"-ын хувьд эхний нөхцөл үнэн, "Учиртай гурван толгой"-н хувьд хоёр дахь нь үнэн тул хоёулаа үлдсэн. Бусад номын хувьд хоёр нөхцөл хоёулаа худал.
Монгол хэлний нэг онцлогийг анхааръя. Ярианы хэлэнд бид "роман болон жүжгийг олж өг" гэж хэлдэг бөгөөд "болон" гэдэг үг нь AND шиг сонсогддог. Гэвч SQL-ийн нүдээр бол нэг ном нэгэн зэрэг роман бөгөөд жүжиг байж чадахгүй — genre = 'Роман' AND genre = 'Жүжиг' гэж бичвэл хоосон үр дүн гарна. Ярианд "болон" гэж хэлж байгаа зүйл SQL-д ихэвчлэн OR болдог. Query-г чангаар уншихдаа "эсвэл" гэдэг үгийг ашиглавал энэ төөрөгдлөөс сэргийлнэ.
Жишээ 5: NOT — нөхцлийг эсрэгээр нь эргүүлэх
Програмчлалын бус бүх номыг олъё. Query:
sql
SELECT title, genre
FROM books
WHERE NOT genre = 'Програмчлал';Үр дүн:
title | genre
----------------------+------
Монголын нууц товчоо | Түүх
Тунгалаг Тамир | Роман
Учиртай гурван толгой | ЖүжигЭнэ query юу гэж хэлж байна вэ гэвэл: “books хүснэгтээс genre нь 'Програмчлал' биш байгаа мөрүүдийг харуул.” NOT нь араас нь ирэх нөхцлийг эсрэгээр нь эргүүлдэг: үнэнийг худал, худлыг үнэн болгодог. Энэ жишээнд NOT genre = 'Програмчлал' нь genre <> 'Програмчлал'-тай яг ижил үр дүн өгнө. Энгийн нөхцөлд <> нь илүү товч, ойлгомжтой байдаг ч NOT-ийн жинхэнэ хүч нь дараагийн хичээлүүдэд нийлмэл нөхцлийг, эсвэл LIKE, IN зэрэг хэрэгслийг эргүүлэх үед илэрнэ.
Одоо энэ хичээлийн хамгийн чухал хэсэг ирлээ. AND болон OR-ийг нэг нөхцөлд хольж бичих үед өгөгдлийн сан аль нь түрүүлж ажиллахыг тогтсон дүрмээр шийддэг: AND нь OR-оос түрүүлж ажилладаг. Энэ нь математикт үржүүлэх нь нэмэхээс түрүүлдэгтэй адил. Хэрэв та энэ дүрмийг мартвал query алдаагүй ажиллаж, гэхдээ буруу мөрүүд буцаана.
Жишээ авъя. Бид “3-аас багагүй хувьтай, програмчлал эсвэл роман номнууд”-ыг хайж байна. Хаалтгүйгээр бичвэл:
sql
SELECT title, genre, copies
FROM books
WHERE genre = 'Програмчлал' OR genre = 'Роман' AND copies >= 3;Үр дүн:
title | genre | copies
-------------------------+-------------+-------
Тунгалаг Тамир | Роман | 3
Clean Code | Програмчлал | 4
Python Crash Course | Програмчлал | 5
The Pragmatic Programmer | Програмчлал | 2“The Pragmatic Programmer” ердөө 2 хувьтай мөртлөө үр дүнд орсон байна. Яагаад? Учир нь өгөгдлийн сан AND-ийг түрүүлж холбож, query-г ингэж ойлгосон: “genre нь програмчлал, ЭСВЭЛ (genre нь роман бөгөөд copies нь 3-аас багагүй)”. Өөрөөр хэлбэл хувийн тооны нөхцөл зөвхөн романд хамаарч, програмчлалын номнууд хувийн тооноос үл хамааран бүгд нэвтэрсэн. Алдааны мессеж гараагүй — SQLite таны бичсэнийг яг үнэн зөв гүйцэтгэсэн, зүгээр л таны бодсоныг биш.
Одоо хаалт нэмье:
sql
SELECT title, genre, copies
FROM books
WHERE (genre = 'Програмчлал' OR genre = 'Роман') AND copies >= 3;Үр дүн:
title | genre | copies
--------------------+-------------+-------
Тунгалаг Тамир | Роман | 3
Clean Code | Програмчлал | 4
Python Crash Course | Програмчлал | 5Энэ query юу гэж хэлж байна вэ гэвэл: “books хүснэгтээс (genre нь програмчлал эсвэл роман) бөгөөд copies нь 3 буюу түүнээс их мөрүүдийг харуул.” Хаалт нь OR-ийг түрүүлж ажиллуулахыг албаддаг тул хувийн тооны нөхцөл одоо бүх номд хамаарч байна. “The Pragmatic Programmer” (2 хувь) зөв хасагдлаа.
Эндээс гарах практик дүрэм энгийн: нэг нөхцөлд AND болон OR зэрэг орвол хаалтыг үргэлж бич. Дүрмийг санаж байсан ч хаалт нь query-г уншиж буй дараагийн хүнд (гурван сарын дараах өөрт тань ч) таны санааг шууд харуулдаг. Хэрэгтэй үед ч, хэрэггүй мэт санагдсан үед ч хаалт хэзээ ч хор хөнөөл учруулдаггүй. Энэ дүрэм Python-д ч мөн адил хамаатай бөгөөд Python ч мөн and-ийг or-оос түрүүлж ажиллуулдаг.
Хэрэв сонирхож байвал members хүснэгтээс 2024 онд элссэн гишүүдийг, эсвэл Улаанбаатарт амьдардаг бөгөөд 2023 оноос хойш элссэн гишүүдийг олж үзээрэй. Ажиллуулахаасаа өмнө query-г чангаар уншиж, ямар нэрс гарч ирэхийг хүснэгтээс таамаглаад, дараа нь шалгаарай. Мөн хаалтны жишээн дээрх хоёр query-г өөрийн гараар бичиж ажиллуулаад, үр дүнгийн ялгааг өөрийн нүдээр харж болно. Эдгээр нь зөвхөн санал бөгөөд дараагийн хичээлүүд тэдгээрийг хийсэн гэж тооцохгүй.
Текстийг хашилтгүй бичих. WHERE genre = Роман гэж хашилтгүй бичвэл no such column: Роман гэсэн алдаа гарна. Энэ мессеж юу гэж хэлж байна вэ гэвэл: "Роман гэдэг нэртэй багана байхгүй байна." Хашилтгүй үг SQL-ийн нүдээр баганын нэр болдог тул SQLite “genre баганын утгыг Роман баганын утгатай харьцуул” гэж ойлгоод ийм багана хайсан. Засах арга нь текстийг дан хашилтаар хүрээлэх: 'Роман'.
Давхар хашилт ашиглах. Python-д текстийг давхар хашилтаар бичдэг тул WHERE genre = "Роман" гэж бичих нь элбэг. SQLite үүнийг ихэнхдээ хүлээн авч ажиллуулдаг ч энэ нь SQLite-ийн өршөөл бөгөөд SQL-ийн стандартад давхар хашилт нь баганын нэрийг илэрхийлдэг. PostgreSQL дээр яг ийм query column "Роман" does not exist гэсэн алдаа өгнө. Тиймээс SQL-д текстэд үргэлж дан хашилт ашиглах дадал гаргаарай.
AND-ийн хоёр талд бүтэн нөхцөл бичихгүй байх. "Он нь 1950-аас их бөгөөд 2010-аас бага" гэж бодоод WHERE year > 1950 AND < 2010 гэж бичвэл near "<": syntax error гэсэн алдаа гарна. Утга нь “< тэмдгийн ойролцоо дүрэм зөрчигдлөө.” AND-ийн хоёр тал тус бүр бүтэн нөхцөл байх ёстой бөгөөд хоёр дахь талд юуг юутай харьцуулахыг заагаагүй байна. Зөв хэлбэр нь WHERE year > 1950 AND year < 2010. Python-д ч мөн яг ийм алдаа гардаг тул энэ нь танд танил байх магадлалтай.
Тэмдгийн дарааллыг солих. WHERE year => 2000 гэж бичвэл near ">": syntax error гарна. SQL зөвхөн >= (эхлээд их, дараа нь тэнцүү) хэлбэрийг таньдаг. Санахад хялбар арга нь монголоор уншсан дараалал: "их буюу тэнцүү" — их нь эхэнд.
AND, OR холих үед хаалт орхих. Энэ нь алдааны мессеж өгдөггүй тул хамгийн аюултай нь юм. Дээрх Хаалтны үнэн хэсэгт харсанчлан query ажиллаж, илүү мөр буцаана. Үр дүнд таны нөхцөлд таарахгүй мөр байвал хаалтаа эхлээд шалгаарай.
Энэ хичээлд та WHERE-ээр мөрүүдийг шүүж сурлаа. WHERE нь мөр бүрийг нөхцлөөр шалгаж, үнэн гарсныг л үлдээдэг. Харьцуулахдаа =, <>, <, >, <=, >= тэмдгүүдийг ашиглах бөгөөд тэнцүүг ганц =-ээр, текстийг дан хашилтаар бичнэ. AND нь хоёр нөхцөл хоёулаа үнэн байхыг, OR нь дор хаяж нэг нь үнэн байхыг, NOT нь нөхцлийг эсрэгээр нь эргүүлэхийг шаарддаг — Python-ы логик тань SQL-д бараг өөрчлөгдөлгүй ажиллаж байна. AND нь OR-оос түрүүлж ажилладаг тул тэдгээрийг хольж бичихдээ үргэлж хаалт ашиглана.
Дараагийн хичээлд бид WHERE-ийн хүчийг улам нэмэгдүүлэх гурван хэрэгсэл сурна. LIKE нь текстийн хэв маягаар хайх (“Python” гэдэг үгтэй бүх ном), IN нь утгын жагсаалтаар шүүх (OR-ийг олон дахин давтахын оронд), BETWEEN нь хоёр хязгаарын хоорондох утгыг олох боломж олгоно.
Бүртгэлтэй болсноор энэ сургалтын бүх хичээлд хандах эрх авна.