ការ Query ដោយ SELECT

មាតិកា

  1. ការសួរសំណួរ
  2. ការជ្រើសរើស Column និង Alias
  3. ការច្រោះដោយ WHERE
  4. AND, OR, NOT និងអាទិភាព
  5. IN និង BETWEEN
  6. ការផ្គូផ្គងលំនាំដោយ LIKE
  7. NULL និង Three-Valued Logic
  8. ការតម្រៀបដោយ ORDER BY
  9. LIMIT និង OFFSET
  10. DISTINCT
  11. Expression និង Function
  12. CASE៖ If/Else ក្នុង SQL
  13. លំដាប់ដែល SQL ដំណើរការពិតប្រាកដ
  14. ការរក្សាទុក Query របស់អ្នក
  15. សាកល្បងដោយខ្លួនឯង

1. ការសួរសំណួរ

រហូតមកដល់ពេលនេះ អ្នកបានសរសេររចនាសម្ព័ន្ធនៃ database និងដាក់ទិន្នន័យចូលក្នុងវា។ ឥឡូវនេះមកដល់ផ្នែកដែលមនុស្សភាគច្រើនមានន័យនៅពេលពួកគេនិយាយថា "SQL"៖ SELECT ជាសេចក្តីថ្លែងដែលអានទិន្នន័យ។ វាជា DQL នៃបីប្រភេទពីជំពូកទី 1 (មនុស្សមួយចំនួនរាប់វាជាផ្នែកមួយនៃ DML) ហើយវាជាអ្វីដែលអ្នកនឹងសរសេរ 90 ភាគរយនៃពេលវេលា។

សូមប្រាកដថា table របស់អ្នកមានទិន្នន័យ seed។ ពីថត shopdb/៖

docker exec -i shopdb-pg psql -U postgres -d shopdb < seed.sql
docker exec -it shopdb-pg psql -U postgres -d shopdb

query សាមញ្ញបំផុតអានអ្វីៗទាំងអស់ពី table មួយ៖

SELECT * FROM products;

* មានន័យថា "column ទាំងអស់"។ វាល្អសម្រាប់ការមើលរហ័ស ប៉ុន្តែអាក្រក់ក្នុងកូដកម្មវិធី៖ អ្នកទាញទិន្នន័យដែលអ្នកមិនប្រើ ហើយកូដរបស់អ្នកផ្លាស់ប្តូរឥរិយាបថនៅពេលនរណាម្នាក់បន្ថែម column។ ក្នុងកូដពិត សូមដាក់ឈ្មោះ column ដែលអ្នកត្រូវការ។

SELECT មានផ្នែកស្រេចចិត្តមួយចំនួនដែលតែងតែលេចឡើងតាមលំដាប់ដូចគ្នា។ នេះជារូបរាងទាំងមូល ហើយជំពូកនេះបំពេញផ្នែកនីមួយៗ៖

SELECT   columns or expressions
FROM     table
WHERE    row filter
ORDER BY sort order
LIMIT    how many rows;

keyword មិនប្រកាន់អក្សរធំតូចទេ (select ដំណើរការដូច SELECT) ប៉ុន្តែការសរសេរវាជាអក្សរធំ និងចាប់ផ្តើម clause នីមួយៗនៅលើបន្ទាត់ផ្ទាល់ខ្លួន ធ្វើឱ្យ query ងាយអាន។ ទិន្នន័យក្នុងសញ្ញាអញ្ញប្រកាស ប្រកាន់ អក្សរធំតូច ហើយរឿងនេះសំខាន់៖ category = 'books' រកមិនឃើញអ្វីទេ ព្រោះតម្លៃដែលរក្សាទុកគឺ 'Books'។

2. ការជ្រើសរើស Column និង Alias

ចុះបញ្ជី column ដែលអ្នកចង់បាន បំបែកដោយសញ្ញាក្បៀស។ លទ្ធផលមានពួកវាតាមលំដាប់នោះ៖

SELECT name, price FROM products;

អ្នកអាចប្តូរឈ្មោះ column ក្នុងលទ្ធផលដោយ AS។ នេះហៅថា alias៖

SELECT name AS product, price AS unit_price
FROM products
LIMIT 3;
       product       | unit_price
---------------------+------------
 Wireless Mouse      |      15.00
 USB-C Cable         |       5.50
 Mechanical Keyboard |      79.00
(3 rows)

(បើគ្មាន ORDER BY database មានសេរីភាពក្នុងការត្រឡប់ row តាមលំដាប់ណាក៏បាន។ លើ table តូចដែលមិនទាន់ប៉ះពាល់ អ្នកជាធម្មតានឹងទទួលបានលំដាប់នៃការបញ្ចូល ប៉ុន្តែកុំពឹងផ្អែកលើវាឡើយ។ ផ្នែកទី 8 គ្របដណ្តប់ការតម្រៀប។)

Alias មិនផ្លាស់ប្តូរ table ទេ។ វាគ្រាន់តែដាក់ឈ្មោះក្នុងលទ្ធផល ដែលសំខាន់ជាងនៅពេល column ត្រូវបានគណនា ដូចក្នុងផ្នែកទី 11។ ប្រសិនបើ alias មានចន្លោះ ឬអក្សរធំ សូមដាក់វាក្នុងសញ្ញាអញ្ញប្រកាសទ្វេ៖ AS "Unit Price"។

3. ការច្រោះដោយ WHERE

WHERE រក្សាតែ row ដែលលក្ខខណ្ឌពិត។ ទាំងនេះជា operator ប្រៀបធៀប៖

Operatorអត្ថន័យ
=ស្មើ (សញ្ញាស្មើមួយ មិនមែនពីរទេ)
<> ឬ !=មិនស្មើ
<, >តូចជាង, ធំជាង
<=, >=តូចជាងឬស្មើ, ធំជាងឬស្មើ

តើផលិតផលណាខ្លះមានតម្លៃក្រោម 20 ដោយចាប់ពីថោកបំផុត?

SELECT name, price
FROM products
WHERE price < 20
ORDER BY price;
      name      | price
----------------+-------
 USB-C Cable    |  5.50
 Coffee Mug     |  6.00
 Notebook Pack  |  9.50
 Wireless Mouse | 15.00
(4 rows)

string និងលេខប្រៀបធៀបបានធម្មជាតិ។ តម្លៃអក្សរដាក់ក្នុងសញ្ញាអញ្ញប្រកាសតែមួយ ចំណែកលេខមិនដាក់ទេ៖

SELECT name, stock FROM products WHERE stock = 0;
    name   | stock
-----------+-------
 Desk Lamp |     0
(1 row)

គិតពី WHERE ដូច function ដែលគ្រប់ row ត្រូវបានបញ្ជូនកាត់៖ database ពិនិត្យលក្ខខណ្ឌសម្រាប់ row នីមួយៗ ហើយរក្សាវាប្រសិនបើចម្លើយពិត។

4. AND, OR, NOT និងអាទិភាព

បញ្ចូលលក្ខខណ្ឌដោយ AND (ទាំងពីរត្រូវតែពិត), OR (យ៉ាងហោចណាស់មួយ) និង NOT (ត្រឡប់វា)។

SELECT name, price
FROM products
WHERE category = 'Books' AND price > 10
ORDER BY name;
     name     | price
--------------+-------
 Clean Code   | 28.50
 SQL Cookbook | 32.00
(2 rows)

ឥឡូវនេះជាអន្ទាក់។ AND ភ្ជាប់តឹងជាង OR ដូចគ្នានឹង * ភ្ជាប់តឹងជាង + ក្នុងនព្វន្ត។ ឧបមាថាអ្នកចង់បាន "របស់ Books ឬ Home ដែលមានតម្លៃក្រោម 10"។ នេះមើលទៅត្រឹមត្រូវ៖

SELECT name, category, price
FROM products
WHERE category = 'Books' OR category = 'Home' AND price < 10
ORDER BY id;
     name      | category | price
---------------+----------+-------
 SQL Cookbook  | Books    | 32.00
 Clean Code    | Books    | 28.50
 Coffee Mug    | Home     |  6.00
 Notebook Pack | Books    |  9.50
(4 rows)

ប៉ុន្តែ SQL អានវាជា Books OR (Home AND price < 10) ដូច្នេះសៀវភៅទាំងអស់ត្រឡប់មកមិនថាតម្លៃប៉ុន្មានទេ។ បន្ថែមវង់ក្រចកដើម្បីនិយាយអ្វីដែលអ្នកមានន័យ៖

SELECT name, category, price
FROM products
WHERE (category = 'Books' OR category = 'Home') AND price < 10
ORDER BY id;
     name      | category | price
---------------+----------+-------
 Coffee Mug    | Home     |  6.00
 Notebook Pack | Books    |  9.50
(2 rows)

ច្បាប់៖ នៅពេលណាអ្នកលាយ AND និង OR សូមប្រើវង់ក្រចក ទោះបីជាមិនតម្រូវយ៉ាងតឹងរ៉ឹងក៏ដោយ។ ខ្លួនអ្នកនៅអនាគតនឹងអរគុណអ្នក។

5. IN និង BETWEEN

បញ្ជីនៃ OR លើ column ដូចគ្នាគឺវែងពេក។ IN និយាយរឿងដូចគ្នាខ្លីជាង៖

SELECT name, category
FROM products
WHERE category IN ('Books', 'Home')
ORDER BY id;
     name      | category
---------------+----------
 SQL Cookbook  | Books
 Clean Code    | Books
 Desk Lamp     | Home
 Coffee Mug    | Home
 Notebook Pack | Books
(5 rows)

NOT IN ផ្តល់ផ្ទុយ។ (ផ្នែកទី 7 មានការភ្ញាក់ផ្អើលអាក្រក់មួយអំពីវា។)

BETWEEN ពិនិត្យជួរ ហើយ ចុងទាំងពីរត្រូវបានរួមបញ្ចូល៖

SELECT name, price
FROM products
WHERE price BETWEEN 10 AND 30
ORDER BY price;
      name      | price
----------------+-------
 Wireless Mouse | 15.00
 Desk Lamp      | 22.00
 Clean Code     | 28.50
(3 rows)

វាគ្រាន់តែជាអក្សរកាត់នៃ price >= 10 AND price <= 30។ វាដំណើរការលើលេខ កាលបរិច្ឆេទ និងអក្សរ។

6. ការផ្គូផ្គងលំនាំដោយ LIKE

ពេលខ្លះអ្នកមិនដឹងអក្សរពិតប្រាកដទេ។ LIKE ផ្គូផ្គងលំនាំដោយ wildcard ពីរ៖

  • % តំណាងឱ្យចំនួនតួអក្សរណាក៏បាន រួមទាំងគ្មានតួអក្សរ។
  • _ តំណាងឱ្យតួអក្សរតែមួយយ៉ាងពិតប្រាកដ។
SELECT name FROM products WHERE name LIKE 'C%';
    name
------------
 Clean Code
 Coffee Mug
(2 rows)

នោះរកឈ្មោះដែល ចាប់ផ្តើម ដោយ C។ USB-C Cable មិនត្រូវបានរួមបញ្ចូលទេ ព្រោះវាចាប់ផ្តើមដោយ U។ ដើម្បីរកពាក្យនៅកន្លែងណាក៏បានក្នុងអក្សរ សូមដាក់ % នៅទាំងសងខាង៖

SELECT name FROM products WHERE name LIKE '%Cable%';
    name
-------------
 USB-C Cable
(1 row)

LIKE ប្រកាន់អក្សរធំតូច។ Postgres បន្ថែម ILIKE ដែលជាកំណែមិនប្រកាន់អក្សរធំតូច ដែលងាយស្រួលសម្រាប់ស្វែងរកអ្វីដែលអ្នកប្រើបានវាយ៖

SELECT name FROM products WHERE name ILIKE '%mouse%';
      name
----------------
 Wireless Mouse
(1 row)

ការផ្គូផ្គងលំនាំគឺល្អសម្រាប់ table តូចៗ។ ការស្វែងរកអក្សរចំនួនច្រើនត្រូវការឧបករណ៍ផ្សេង (full-text search) ហើយលំនាំដែលចាប់ផ្តើមដោយ % មិនអាចប្រើ index ធម្មតាបានទេ ជាចំណុចដែលយើងត្រឡប់មកវិញក្នុងជំពូកទី 11។

7. NULL និង Three-Valued Logic

អ្នកបានជួប NULL ក្នុងជំពូកទី 3៖ វាមានន័យថា "មិនដឹង ឬបាត់" មិនមែនសូន្យ និងមិនមែន string ទទេទេ។ ក្នុង shopdb Maly Ros មាន NULL សម្រាប់ city។ សូមមើលអ្វីដែលកើតឡើងនៅពេលអ្នកសួររកនាងតាមវិធីជាក់ស្តែង៖

SELECT name FROM customers WHERE city = NULL;
 name
------
(0 rows)

គ្មានកំហុស និងគ្មាន row។ មូលហេតុ៖ ការប្រៀបធៀបអ្វីមួយជាមួយតម្លៃមិនស្គាល់ផ្តល់លទ្ធផលមិនស្គាល់ មិនមែនពិត ឬមិនពិតទេ។ សូម្បីតែ NULL = NULL ក៏មិនស្គាល់ដែរ ព្រោះរបស់មិនស្គាល់ពីរមិនត្រូវបានដឹងថាស្មើគ្នាទេ។

ដូច្នេះ SQL មាន បី តម្លៃពិត៖ ពិត មិនពិត និងមិនស្គាល់។ ហើយ WHERE រក្សា row លុះត្រាតែលក្ខខណ្ឌ ពិត។ តម្លៃមិនស្គាល់ត្រូវបានទម្លាក់ ដូចតម្លៃមិនពិត។ ដើម្បីសាកល្បង NULL អ្នកត្រូវការ operator ពិសេស៖

SELECT name, city FROM customers WHERE city IS NULL;
   name   | city
----------+------
 Maly Ros |
(1 row)

(psql បង្ហាញ NULL ជាក្រឡាទទេតាមលំនាំដើម។) ប្រើ IS NOT NULL សម្រាប់ផ្ទុយ។

តក្កវិជ្ជាដូចគ្នាបង្កឱ្យមានកំហុសស្ងាត់ជាង។ តើអតិថិជនណាខ្លះ មិន រស់នៅ Phnom Penh?

SELECT name, city FROM customers WHERE city <> 'Phnom Penh';
   name    |    city
-----------+------------
 Dara Kim  | Siem Reap
 Vuthy Sok | Battambang
(2 rows)

Maly បាត់។ city របស់នាងមិនស្គាល់ ដូច្នេះ "មិនស្គាល់ មិនមែន Phnom Penh" ខ្លួនវាក៏មិនស្គាល់ដែរ ហើយ row ត្រូវបានទម្លាក់។ ថាតើនោះត្រឹមត្រូវឬអត់ អាស្រ័យលើសំណួររបស់អ្នក ប៉ុន្តែជារឿយៗវាមិនមែនជាអ្វីដែលអ្នកចង់បានទេ។ ដំណោះស្រាយពីរ៖

-- ប្រាប់ឱ្យច្បាស់លាស់
WHERE city <> 'Phnom Penh' OR city IS NULL

-- ឬប្រើការប្រៀបធៀបដែលសុវត្ថិភាពចំពោះ NULL
WHERE city IS DISTINCT FROM 'Phnom Penh'

ទាំងពីរវិធីត្រឡប់ Dara, Vuthy និង Maly។

អន្ទាក់ទីបី៖ NOT IN ជាមួយបញ្ជីដែលមាន NULL ត្រឡប់គ្មានអ្វីសោះ។

SELECT name FROM customers WHERE city NOT IN ('Phnom Penh', NULL);
 name
------
(0 rows)

សម្រាប់អតិថិជននីមួយៗ SQL ពិនិត្យ city <> 'Phnom Penh' AND city <> NULL។ ផ្នែកទីពីរមិនដែលពិតទេ ដូច្នេះទាំងមូលមិនដែលពិតទេ។ នេះចាប់មនុស្សនៅពេលបញ្ជីមកពី subquery ដែលចៃដន្យមាន NULL (ជំពូកទី 9 បង្ហាញជម្រើសសុវត្ថិភាព NOT EXISTS)។

សេចក្តីសង្ខេប៖ កុំប្រើ = NULL ជាដាច់ខាត ត្រូវគិតជានិច្ចអំពីអ្វីដែល NULL ធ្វើក្នុងលក្ខខណ្ឌ ហើយនៅពេល query "បាត់" row សូមសង្ស័យ NULL។

8. ការតម្រៀបដោយ ORDER BY

បើគ្មាន ORDER BY លំដាប់ row មិនត្រូវបានធានាទេ។ ដើម្បីតម្រៀប សូមដាក់ឈ្មោះ column។ បន្ថែម DESC សម្រាប់ចុះ (ឡើងជាលំនាំដើម)៖

SELECT name, price FROM products ORDER BY price DESC;

តម្រៀបតាម column ច្រើន៖ column ក្រោយបំបែកភាពស្មើគ្នាក្នុង column មុន។

SELECT category, name, price
FROM products
ORDER BY category, price DESC;
  category   |        name         | price
-------------+---------------------+-------
 Books       | SQL Cookbook        | 32.00
 Books       | Clean Code          | 28.50
 Books       | Notebook Pack       |  9.50
 Electronics | Mechanical Keyboard | 79.00
 Electronics | Wireless Mouse      | 15.00
 Electronics | USB-C Cable         |  5.50
 Home        | Desk Lamp           | 22.00
 Home        | Coffee Mug          |  6.00
(8 rows)

ប្រភេទឡើងតាមលំដាប់អក្ខរក្រម ហើយក្នុងប្រភេទនីមួយៗ តម្លៃចុះ។ តើ NULL ទៅកន្លែងណា? ក្នុង Postgres លំដាប់ឡើងដាក់វា ចុងក្រោយ ហើយលំដាប់ចុះដាក់វាមុនគេ។ អ្នកអាចជ្រើសរើសបាន៖

SELECT name, city FROM customers ORDER BY city NULLS FIRST, name;

បើគ្មាន NULLS FIRST Maly នឹងលេចឡើងនៅខាងក្រោមនៃការតម្រៀបឡើង។

9. LIMIT និង OFFSET

LIMIT n ត្រឡប់ច្រើនបំផុត n row។ បញ្ចូលគ្នាជាមួយ ORDER BY វាឆ្លើយសំណួរ "top N"៖ ផលិតផលថ្លៃបំផុតទាំងបី។

SELECT name, price
FROM products
ORDER BY price DESC
LIMIT 3;
        name         | price
---------------------+-------
 Mechanical Keyboard | 79.00
 SQL Cookbook        | 32.00
 Clean Code          | 28.50
(3 rows)

OFFSET n រំលង n row ដំបូង ដែលជារបៀបដែលទំព័រដំណើរការ។ ទំព័រទី 2 នៃបញ្ជីដែលមាន 3 ក្នុងមួយទំព័រ៖

SELECT name, price
FROM products
ORDER BY price DESC
LIMIT 3 OFFSET 3;
      name      | price
----------------+-------
 Desk Lamp      | 22.00
 Wireless Mouse | 15.00
 Notebook Pack  |  9.50
(3 rows)

ការព្រមានពីរ។ ទីមួយ LIMIT ដែលគ្មាន ORDER BY ត្រឡប់សំណុំ row តាមអំពើចិត្ត ដូច្នេះត្រូវតម្រៀបជានិច្ចនៅពេលអ្នកចែកទំព័រ ហើយតម្រៀបតាមអ្វីដែល unique (បន្ថែម id ជាអ្នកបំបែកភាពស្មើគ្នាចុងក្រោយ) ដើម្បីកុំឱ្យទំព័រត្រួតគ្នា។ ទីពីរ OFFSET 100000 នៅតែធ្វើឱ្យ database ដើរកាត់ 100,000 row មុនពេលត្រឡប់របស់អ្នក។ មិនអីសម្រាប់ table តូច ប៉ុន្តែយឺតសម្រាប់ table ធំ។

10. DISTINCT

DISTINCT លុប row ស្ទួនពីលទ្ធផល។ តើអតិថិជនរបស់យើងរស់នៅទីក្រុងណាខ្លះ?

SELECT DISTINCT city FROM customers ORDER BY city;
    city
------------
 Battambang
 Phnom Penh
 Siem Reap

(4 rows)

Phnom Penh លេចឡើងម្តង ទោះបីអតិថិជនពីរនាក់រស់នៅទីនោះ។ row ចុងក្រោយគឺ NULL (បង្ហាញជាបន្ទាត់ទទេ) តម្រៀបនៅចុងក្រោយព្រោះយើងប្រើលំដាប់ឡើងលំនាំដើម។ DISTINCT ចាត់ទុក NULL ទាំងអស់ថាដូចគ្នា។

SELECT DISTINCT category FROM products ORDER BY category;
  category
-------------
 Books
 Electronics
 Home
(3 rows)

DISTINCT អនុវត្តលើ row ទាំងមូលនៃ column ដែលបានជ្រើស មិនមែនលើ column តែមួយទេ។ SELECT DISTINCT category, price លុបតែ row ដែលតម្លៃទាំងពីរស្ទួន។ ប្រសិនបើអ្នកឃើញខ្លួនឯងបន្ថែម DISTINCT ដើម្បីធ្វើឱ្យ query "មើលទៅត្រឹមត្រូវ" សូមឈប់បន្តិច៖ វាច្រើនតែលាក់កំហុស ដូចដែលអ្នកនឹងឃើញជាមួយ join ក្នុងជំពូកទី 7។

11. Expression និង Function

បញ្ជី SELECT មិនកំណត់តែ column ទេ។ វាអាចមាន expression ណាក៏បាន៖ នព្វន្ត ប្រតិបត្តិការអក្សរ ការហៅ function។ នេះជាការឡើងតម្លៃ 10 ភាគរយ បង្គត់ទៅសេន៖

SELECT name, price, round(price * 1.10, 2) AS with_tax
FROM products
WHERE id <= 3;
        name         | price | with_tax
---------------------+-------+----------
 Wireless Mouse      | 15.00 |    16.50
 USB-C Cable         |  5.50 |     6.05
 Mechanical Keyboard | 79.00 |    86.90
(3 rows)

តើមានលុយប៉ុន្មាននៅលើធ្នើសម្រាប់ផលិតផលនីមួយៗ? តម្លៃគុណនឹងស្តុក។ បង្ហាញបីដំបូង៖

SELECT name, price * stock AS stock_value
FROM products
ORDER BY stock_value DESC
LIMIT 3;
        name         | stock_value
---------------------+-------------
 Mechanical Keyboard |     1185.00
 Clean Code          |      855.00
 SQL Cookbook        |      800.00
(3 rows)

ចំណាំថា ORDER BY អាចប្រើ alias stock_value។ (ផ្នែកទី 13 ពន្យល់ហេតុអ្វី WHERE មិនអាច។)

function មួយចំនួនដែលអ្នកនឹងប្រើគ្រប់ពេល៖

Functionឧទាហរណ៍លទ្ធផល
upper(text), lower(text)upper('abc')ABC
length(text)length('USB-C Cable')11
round(n, digits)round(2.456, 2)2.46
a || b'Coffee' || ' Mug'Coffee Mug
concat(a, b, ...)concat('a', NULL, 'b')ab
coalesce(a, b, ...)coalesce(NULL, 'x')x

ពីរក្នុងចំណោមទាំងនេះសមនឹងមានមតិយោបល់។ operator || ភ្ជាប់អក្សរ ប៉ុន្តែត្រឡប់ NULL ប្រសិនបើខាងណាមួយជា NULL ចំណែក concat() គ្រាន់តែរំលង NULL។

coalesce ត្រឡប់ argument ដំបូងរបស់វាដែលមិនមែន NULL ដែលធ្វើឱ្យវាជារបៀបស្តង់ដារក្នុងការជំនួស NULL ដោយតម្លៃលំនាំដើមសម្រាប់ការបង្ហាញ៖

SELECT name, coalesce(city, 'unknown') AS city
FROM customers
ORDER BY id;
    name    |    city
------------+------------
 Sokha Chan | Phnom Penh
 Dara Kim   | Siem Reap
 Linda Vong | Phnom Penh
 Vuthy Sok  | Battambang
 Maly Ros   | unknown
(5 rows)

កាលបរិច្ឆេទ និងពេលវេលាមាននព្វន្តផ្ទាល់ខ្លួន។ ការដក interval ពី timestamp ផ្លាស់ទីវាថយក្រោយក្នុងពេលវេលា៖

SELECT now() - interval '30 days' AS thirty_days_ago;
SELECT current_date;
SELECT name FROM customers WHERE created_at > now() - interval '1 day';

query ចុងក្រោយមានន័យថា "អតិថិជនដែលបានចុះឈ្មោះក្នុងមួយថ្ងៃចុងក្រោយ"។ កាលបរិច្ឆេទជាប្រធានបទជ្រៅ៖ ជំពូកទី 8 ប្រើ date_trunc ដើម្បីដាក់ក្រុម order តាមខែ។

អ្នកក៏អាចដំណើរការ query ដែលគ្មាន table សោះផងដែរ ដូចអ្នកបានធ្វើក្នុងជំពូកទី 2 ជាមួយ SELECT 1 + 1។ នោះងាយស្រួលសម្រាប់សាកល្បង function។

12. CASE៖ If/Else ក្នុង SQL

CASE គឺជា if / else if / else របស់ SQL។ វាត្រឡប់តម្លៃ ដូច្នេះអ្នកប្រើវាក្នុង SELECT។ នៅទីនេះយើងដាក់ស្លាកកម្រិតស្តុករបស់ផលិតផលនីមួយៗ៖

SELECT
  name,
  stock,
  CASE
    WHEN stock = 0 THEN 'out of stock'
    WHEN stock < 20 THEN 'low'
    ELSE 'ok'
  END AS stock_status
FROM products
ORDER BY id;
        name         | stock | stock_status
---------------------+-------+--------------
 Wireless Mouse      |    40 | ok
 USB-C Cable         |   120 | ok
 Mechanical Keyboard |    15 | low
 SQL Cookbook        |    25 | ok
 Clean Code          |    30 | ok
 Desk Lamp           |     0 | out of stock
 Coffee Mug          |    80 | ok
 Notebook Pack       |    60 | ok
(8 rows)

សាខាត្រូវបានពិនិត្យពីលើចុះក្រោម ហើយការផ្គូផ្គងដំបូងឈ្នះ ដូច្នេះលំដាប់សំខាន់៖ ស្តុក 0 ក៏តូចជាង 20 ដែរ ប៉ុន្តែ WHEN ដំបូងចាប់វា។ ប្រសិនបើគ្មានសាខាណាត្រូវគ្នា ហើយគ្មាន ELSE លទ្ធផលគឺ NULL។ CASE ក្លាយជាមានអានុភាពខ្លាំងជាមួយ aggregation ដែលអ្នកនឹងឃើញក្នុងជំពូកទី 8។

13. លំដាប់ដែល SQL ដំណើរការពិតប្រាកដ

អ្នកសរសេរ SELECT មុន ប៉ុន្តែ database មិន ដំណើរការវាមុនទេ។ វាវាយតម្លៃ query តាមតក្កវិជ្ជាតាមលំដាប់នេះ៖

  1. FROM៖ ជ្រើស table (ជំពូកក្រោយ៖ table ដែលបាន join)។
  2. WHERE៖ បោះចោល row ដែលធ្លាក់លក្ខខណ្ឌ។
  3. GROUP BY និង HAVING៖ ដាក់ក្រុម និងច្រោះក្រុម (ជំពូកទី 8)។
  4. SELECT៖ គណនា column លទ្ធផល និង alias។
  5. DISTINCT៖ លុបទិន្នន័យស្ទួន។
  6. ORDER BY៖ តម្រៀប។
  7. LIMIT / OFFSET៖ កាត់លទ្ធផល។

នេះពន្យល់រឿងជាច្រើនដែលបើមិនដូច្នោះមើលទៅដូចតាមអំពើចិត្ត។ ហេតុអ្វី ORDER BY អាចប្រើ alias ប៉ុន្តែ WHERE មិនអាច? ព្រោះ alias ត្រូវបានបង្កើតក្នុងជំហានទី 4 បន្ទាប់ពី WHERE បានដំណើរការរួចហើយ៖

SELECT name, price * 1.1 AS with_tax
FROM products
WHERE with_tax > 10;
ERROR:  column "with_tax" does not exist

(Postgres បន្ថែម LINE និងសញ្ញាចង្អុលទៅបញ្ហា។) សរសេរ expression ម្តងទៀតក្នុងតម្រង WHERE price * 1.1 > 10 នោះវាដំណើរការ។

វាក៏ពន្យល់ផងដែរថាហេតុអ្វី LIMIT តែងតែមកចុងក្រោយ៖ database ត្រូវតម្រៀបអ្វីៗទាំងអស់ជាមុនដើម្បីដឹងថា row ណាជា "top 3"។ ហើយវាពន្យល់ហេតុអ្វី WHERE ច្រោះ row មុនពេលគណនាអ្វីមួយ ដូច្នេះ table តូចជាងទៅដល់ជំហានក្រោយ។ រក្សាលំដាប់នេះក្នុងក្បាលរបស់អ្នក។ វាជាគំរូដែលធ្វើឱ្យផ្នែកដែលនៅសល់នៃស៊េរី ជាពិសេស GROUP BY និង window function សម្រុះសម្រួលគ្នា។

(នេះជាលំដាប់ តក្កវិជ្ជា។ query planner មានសេរីភាពដំណើរការជំហានតាមលំដាប់រូបវន្តផ្សេងដើម្បីល្បឿន ដរាបណាលទ្ធផលដូចគ្នា។ ជំពូកទី 11 បង្ហាញរបៀបមើលផែនការរបស់វា។)

14. ការរក្សាទុក Query របស់អ្នក

អ្នកនឹងចង់រក្សា query ល្អៗ។ នៅក្នុងថត shopdb/ របស់អ្នក ប្រើថត queries/ ពីជំពូកទី 2 ដើម្បីរក្សាឯកសារសម្រាប់ជំពូកនេះ ឧទាហរណ៍ queries/05-select.sql ហើយដាក់ query របស់អ្នកក្នុងវាជាមួយមតិយោបល់៖

-- queries/05-select.sql

-- ផលិតផលក្រោម 20 ថោកបំផុតមុន
SELECT name, price
FROM products
WHERE price < 20
ORDER BY price;

-- ស្លាកស្ថានភាពស្តុក
SELECT name, stock,
  CASE WHEN stock = 0 THEN 'out of stock'
       WHEN stock < 20 THEN 'low'
       ELSE 'ok' END AS stock_status
FROM products
ORDER BY id;

ដំណើរការឯកសារទាំងមូលពេលណាក៏បាន៖

docker exec -i shopdb-pg psql -U postgres -d shopdb < queries/05-select.sql

មិនដូច schema.sql និង seed.sql ទេ ឯកសារទាំងនេះគ្រាន់តែអានទិន្នន័យ ដូច្នេះវាមានសុវត្ថិភាពក្នុងការដំណើរការគ្រប់ពេល។ នេះក៏ជារបៀបដែលក្រុមពិតចែករំលែក និងពិនិត្យ SQL ដែរ៖ ជាឯកសារក្នុង version control។

15. សាកល្បងដោយខ្លួនឯង

ដាក់ចម្លើយរបស់អ្នកក្នុង queries/05-select.sql។

  1. Electronics ថោក។ ចុះបញ្ជីឈ្មោះ និងតម្លៃនៃផលិតផលគ្រប់យ៉ាងក្នុងប្រភេទ Electronics ដែលមានតម្លៃតិចជាង 20 ដោយចាប់ពីថ្លៃបំផុតមុន។ តើអ្នករំពឹងថាមានប៉ុន្មាន row មុនពេលអ្នកដំណើរការវា?
  2. អាទិភាព។ សរសេរ query សម្រាប់ផលិតផលដែលនៅក្នុង Books ឬមានតម្លៃលើស 50 ហើយ មានស្តុកលើស 20។ សរសេរវាម្តងដោយគ្មានវង់ក្រចក និងម្តងទៀតជាមួយវង់ក្រចក។ តើលទ្ធផលខុសគ្នាទេ? ពន្យល់។
  3. ស្វែងរកលំនាំ។ រកអតិថិជនទាំងអស់ដែល email ចាប់ផ្តើមដោយអក្សរនៅចន្លោះ d និង m ដោយប្រើ LIKE ឬការប្រៀបធៀប ហើយរកផលិតផលទាំងអស់ដែលឈ្មោះមានពាក្យ code មិនថាអក្សរធំឬតូច។
  4. អ្នកស៊ើបអង្កេត NULL។ រកអតិថិជនដែល city បាត់។ បន្ទាប់មកសរសេរ "អតិថិជនដែលមិនរស់នៅ Siem Reap" តាមរបៀបដែលរួមបញ្ចូល Maly ត្រឹមត្រូវ។ ហេតុអ្វី city <> 'Siem Reap' តែមួយមិនរួមបញ្ចូលនាង?
  5. លទ្ធផលបែបរបាយការណ៍។ បង្កើត column មួយឈ្មោះ label ដែលអានដូច Wireless Mouse - $15.00 សម្រាប់ផលិតផលនីមួយៗ (ប្រើ || និង cast ដូចជា price::text) តម្រៀបតាមតម្លៃចុះ កំណត់ត្រឹមប្រាំដំបូង។
  6. លំដាប់នៃការវាយតម្លៃ។ សរសេរ query ដែលប្រើ alias ក្នុង WHERE ហើយអានកំហុស។ បន្ទាប់មកជួសជុលពីរដង៖ ម្តងដោយសរសេរ expression ម្តងទៀត និងម្តងទៀតដោយរុំ query ជា SELECT * FROM (...) AS t WHERE ... (ការមើលជាមុននៃជំពូកទី 9)។

ទៅទីណាបន្ត។ ឥឡូវនេះអ្នកអាចសួរសំណួរជាច្រើនអំពី table តែមួយ។ ប៉ុន្តែទិន្នន័យរបស់ហាងរស់នៅក្នុងច្រើន table៖ អតិថិជនធ្វើ order, order មានផលិតផល។ ជំពូកបន្ទាប់សាងសង់ table ដែលបាត់ទាំងនោះ ហើយភ្ជាប់វាដោយ primary key និង foreign key៖ Keys និង Relationships។

ទិញកាហ្វេជូនខ្ញុំ

ចូលចិត្តមេរៀននេះមែនទេ? សូមពិចារណាទិញកាហ្វេជូនខ្ញុំមួយកែវ ដើម្បីគាំទ្រការបង្កើតមាតិកាឥតគិតថ្លៃបន្ថែមទៀត!