บทความนี้เขียนเพื่อผู้เริ่มต้นที่ยังไม่เคยเขียน SQL มาก่อน เราจะเรียนคำสั่ง SQL ที่จำเป็นครบทุกคำสั่ง ตั้งแต่ CREATE (สร้างฐานข้อมูล/ตาราง), INSERT (เพิ่มข้อมูล), SELECT (ดึงข้อมูล), UPDATE (แก้ไขข้อมูล) ไปจนถึง DELETE (ลบข้อมูล) พร้อมตัวอย่างที่ทำตามได้จริง
ก่อนอื่นมาทำความรู้จักคำศัพท์ 4 คำที่จะใช้ตลอดบทความ:
- ฐานข้อมูล (Database) — เหมือน “โฟลเดอร์” หรือ “สมุดบัญชี” ที่เก็บตารางไว้ข้างใน
- ตาราง (Table) — เหมือน “ตารางใน Excel” มีทั้งแถวและคอลัมน์ เช่น ตาราง
patientเก็บข้อมูลผู้ป่วย - แถว / record — ข้อมูลของคนหรือสิ่งของ หนึ่งหน่วย เช่น ข้อมูลผู้ป่วย 1 คน = 1 แถว
- คอลัมน์ / column — ข้อมูล ชนิดเดียวกัน ทั้งคอลัมน์ เช่น คอลัมน์
weightเก็บแต่น้ำหนัก
ส่วน SQL (อ่านว่า “เอส-คิว-แอล”) คือภาษาที่เราใช้ “พูดคุย” กับฐานข้อมูล เหมือนเราสั่งงานพนักงาน เช่น บอกว่า “เอารายชื่อผู้ป่วยที่น้ำหนักเกิน 100 กิโลกรัมมาให้ดูหน่อย” — ประโยคนี้แปลเป็น SQL ได้ และเราจะเรียนวิธีเขียนไปทีละขั้น
ในบทความนี้เราจะเรียนตามลำดับ: ติดตั้ง CAMPP → เปิด phpMyAdmin → ใช้ CREATE สร้างฐานข้อมูลและตาราง → ใช้ INSERT เพิ่มข้อมูล → ใช้ SELECT ดึงข้อมูล (พร้อม WHERE, ORDER BY, GROUP BY, JOIN) → และใช้ UPDATE แก้ไข กับ DELETE ลบข้อมูล
ไม่ต้องกลัวถ้าไม่เข้าใจทันที — ลองพิมพ์คำสั่งตามจริง ๆ ในเครื่องแล้วดูผลลัพธ์ จะเข้าใจได้เร็วกว่าอ่านอย่างเดียวหลายเท่า
1. ติดตั้ง CAMPP#
ก่อนจะเล่นฐานข้อมูลได้ เราต้องมีโปรแกรมที่เป็นฐานข้อมูลเสียก่อน CAMPP เป็นโปรแกรมฟรีที่รวมเครื่องมือที่จำเป็นไว้ในแพ็กเกจเดียว เปรียบเหมือน “กล่องเครื่องมือ” ที่เปิดปุ๊บใช้ได้เลย ไม่ต้องไปติดตั้งแต่ละอย่างแยกกัน
ภายใน CAMPP มีสิ่งสำคัญ 2 อย่างที่เราจะใช้:
- MySQL / MariaDB — ตัวฐานข้อมูลจริง ๆ (เครื่องมือที่เก็บข้อมูล)
- phpMyAdmin — โปรแกรมหน้าต่าง (เว็บ) ที่ให้เราจัดการฐานข้อมูลผ่านคลิก ๆ หรือพิมพ์ SQL ได้สะดวก
ขั้นตอน:
-
ดาวน์โหลดและติดตั้ง CAMPP จาก https://campp.melivecode.com/ ↗

-
เปิดโปรแกรม CAMPP ขึ้นมา แล้วกดปุ่ม Start เพื่อสั่งให้บริการต่าง ๆ เริ่มทำงาน

เมื่อกด Start แล้ว ให้สังเกตว่าแต่ละบริการแสดงสถานะเป็น “กำลังทำงาน” (สีเขียว/running) แปลว่าพร้อมใช้งานแล้ว หากตัวใดตัวหนึ่งไม่ทำงาน ให้กด Stop แล้วกด Start ใหม่อีกครั้ง
2. เปิด phpMyAdmin#
แม้ MySQL เป็นตัวเก็บข้อมูลจริง แต่มันไม่มีหน้าต่างสวยงามให้คลิก การจะคุยกับมันตรง ๆ ผ่าน command line ค่อนข้างยากสำหรับมือใหม่ phpMyAdmin จึงเปรียบเหมือน “รีโมทคอนโทรล” ที่ทำให้เราควบคุมฐานข้อมูลได้ง่ายผ่านหน้าเว็บ
เข้าใช้งาน phpMyAdmin ได้ 2 วิธี:
-
คลิกปุ่ม phpMyAdmin บนหน้าเว็บของ CAMPP
-
เปิดเบราว์เซอร์แล้วพิมพ์ที่อยู่นี้: http://127.0.0.1:8080/phpmyadmin/ ↗
(
127.0.0.1คือเครื่องของเราเอง และ8080คือพอร์ต — เหมือนเลขห้องที่เว็บนี้อยู่)

ใน phpMyAdmin เราจัดการฐานข้อมูลได้ 2 ทาง:
- ทางที่ 1 — คลิกผ่าน GUI (หน้าต่างกราฟิก) เหมาะกับงานง่าย ๆ เช่น สร้างฐานข้อมูล
- ทางที่ 2 — คลิกแท็บ SQL แล้วพิมพ์คำสั่งเอง เร็วและทรงพลังกว่า คำสั่งทั้งหมดในบทความนี้เราจะรันผ่านแท็บ SQL นี้
ทำไมต้องเรียนพิมพ์ SQL เอง ทั้งที่มี GUI ให้คลิก? เพราะเมื่อทำงานจริง คำสั่ง SQL สามารถเขียนเก็บไว้ในโปรแกรม ส่งให้แอปพลิเคชันรันได้ และทำอะไรที่ซับซ้อนได้มากกว่าการคลิก
3. CREATE DATABASE — สร้างฐานข้อมูล#
เริ่มจากการสร้าง “โฟลเดอร์” ที่จะเก็บตารางต่าง ๆ ของเรา ในที่นี้ตั้งชื่อว่า testdb
-- สร้างฐานข้อมูล (ใช้ IF NOT EXISTS เพื่อไม่ให้ error หากสร้างไว้แล้ว)
CREATE DATABASE IF NOT EXISTS testdb;
-- เลือกฐานข้อมูลที่จะใช้งาน
USE testdb;sqlคำอธิบายทีละบรรทัด:
CREATE DATABASE— สั่ง “สร้างฐานข้อมูลใหม่”IF NOT EXISTS— “ถ้ายังไม่มีนะค่อยสร้าง” ป้องกัน error เวลาเรารันซ้ำ ๆ (เช่น รันครั้งที่สอง ฐานข้อมูลมีแล้ว ปกติจะ error แต่มีคำสั่งนี้ก็ข้ามไป)USE testdb;— “ต่อไปใช้ฐานข้อมูล testdb นะ” เพื่อให้คำสั่งถัดไปตกลงในฐานข้อมูลที่ถูกต้อง


จุดสังเกต: คำสั่ง SQL จะจบด้วยเครื่องหมาย
;(เซมิโคลอน) เสมอ เหมือนจุดมหัพภาคในภาษาไทยที่บอกว่า “จบประโยคแล้ว” แต่ถ้าพิมพ์คำสั่งเดียว หลายครั้งลืมไปก็ไม่ error แต่ถ้าพิมพ์หลายคำสั่งติดกัน ต้องมี;คั่น
4. CREATE TABLE — สร้างตาราง#
ตารางก็เหมือนตารางใน Excel: แถวแรกคือ “หัวตาราง” (ชื่อคอลัมน์) และแถวถัด ๆ ไปคือข้อมูล สิ่งที่ต่างจาก Excel คือ ตอนสร้างตารางเราต้องบอกฐานข้อมูลเลยว่าแต่ละคอลัมน์จะเก็บข้อมูลแบบไร เรียกว่า ชนิดข้อมูล (datatype)
ชนิดข้อมูลที่ใช้บ่อยมีดังนี้:
| ชนิดข้อมูล | เก็บอะไร | ตัวอย่าง |
|---|---|---|
INT | จำนวนเต็ม | ID, อายุ, จำนวน |
VARCHAR(n) | ข้อความสั้น ๆ (ไม่เกิน n ตัวอักษร) | ชื่อ, ที่อยู่, อีเมล |
DATE | วันที่ รูปแบบ YYYY-MM-DD | วันเกิด |
DECIMAL(p,s) | เลขทศนิยมที่ต้องการความแม่นยำ | น้ำหนัก, ราคา, เงิน |
ทำไมต้องกำหนดชนิดข้อมูล? เพราะฐานข้อมูลจะได้จัดเก็บให้ถูกต้อง ประหยัดพื้นที่ และค้นหาได้เร็ว ถ้าคอลัมน์
weightกำหนดเป็นINT(จำนวนเต็ม) เวลาใส่105.50จะถูกตัดเหลือแค่105ส่วนทศนิยมหายไป
เราจะสร้าง 2 ตาราง: province (เก็บจังหวัด) และ patient (เก็บผู้ป่วย)
-- ตาราง province (เก็บข้อมูลจังหวัด)
CREATE TABLE province (
code INT PRIMARY KEY,
name VARCHAR(100)
);
-- ตาราง patient (เก็บข้อมูลผู้ป่วย)
CREATE TABLE patient (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(10),
fname VARCHAR(100),
lname VARCHAR(100),
gender VARCHAR(10),
dob DATE,
province_id INT,
weight DECIMAL(5,2),
height DECIMAL(5,2),
FOREIGN KEY (province_id) REFERENCES province(code)
);sql
คำสำคัญที่ต้องเข้าใจมี 3 ตัว:
PRIMARY KEY(คีย์หลัก) — เป็น “บัตรประจำตัว” ของแต่ละแถว ทำให้แต่ละแถวไม่ซ้ำกันและค้นหาได้เร็ว- ใน
provinceคือcode(เช่น 10 = Bangkok) - ใน
patientคือid(1, 2, 3, …)
- ใน
AUTO_INCREMENT— สั่งให้ฐานข้อมูล “นับเลขให้เอง” (1, 2, 3, …) เวลาเพิ่มข้อมูลใหม่ เราไม่ต้องพิมพ์เลข ID เองFOREIGN KEY(คีย์นอก) — เหมือน “ลิงก์” ที่เชื่อมตารางหนึ่งไปยังอีกตารางหนึ่งFOREIGN KEY (province_id) REFERENCES province(code)แปลว่า: คอลัมน์province_idในตารางpatientชี้ไปที่codeในตารางprovince- ผลคือ เราเก็บแค่ “รหัสจังหวัด” ในตารางผู้ป่วย ไม่ต้องพิมพ์ชื่อจังหวัดซ้ำในทุกแถว (ประหยัดพื้นที่และลดความผิดพลาด)
สำคัญ: ต้องสร้างตาราง
provinceก่อนpatientเพราะpatient“อ้างอิง” ไปที่provinceหากสร้างpatientก่อน ฐานข้อมูลจะ error เพราะยังไม่มีprovinceให้ชี้ไป เหมือนจะสร้างสะพานก่อนสร้างฝั่งที่จะวางตอม่อ — ทำไม่ได้

5. INSERT — เพิ่มข้อมูลตัวอย่าง#
ตอนนี้ตารางยังว่างเปล่า (มีแค่หัวตาราง ยังไม่มีข้อมูล) เราต้องใส่ข้อมูลเข้าไปก่อน จึงจะมีอะไรให้ SELECT ดึงมาดูในหัวข้อถัดไป
-- เพิ่มข้อมูลจังหวัด
INSERT INTO province (code, name) VALUES
(10, 'Bangkok'),
(20, 'Nakhon Ratchasima'),
(30, 'Nakhon Pathom'),
(50, 'Chiang Mai');
-- เพิ่มข้อมูลผู้ป่วย
INSERT INTO patient (title, fname, lname, gender, dob, province_id, weight, height) VALUES
('Mr.', 'John', 'Smith', 'Male', '1985-03-15', 10, 105.00, 175.00),
('Ms.', 'Mary', 'Johnson', 'Female', '1992-07-22', 50, 55.00, 160.00),
('Mr.', 'David', 'Lee', 'Male', '1988-11-30', 10, 112.00, 178.00),
('Mr.', 'Robert', 'Brown', 'Male', '1990-01-05', 20, 80.00, 180.00),
('Ms.', 'Linda', 'Wilson', 'Female', '1995-04-18', 10, 62.00, 158.00),
('Mr.', 'Michael', 'Davis', 'Male', '1983-09-12', 50, 120.00, 175.00),
('Ms.', 'Sarah', 'Miller', 'Female', '1998-06-25', 10, 48.00, 155.00),
('Mr.', 'James', 'Taylor', 'Male', '1987-12-08', 20, 75.00, 172.00),
('Ms.', 'Emily', 'Anderson', 'Female', '1993-02-14', 50, 58.00, 165.00),
('Mr.', 'Thomas', 'Thomas', 'Male', '1980-08-20', 10, 95.00, 168.00),
('Ms.', 'Jessica', 'Jackson', 'Female', '1996-10-03', 10, 70.00, 170.00),
('Mr.', 'Charles', 'White', 'Male', '1982-05-17', 50, 88.00, 185.00);sqlรูปแบบของคำสั่ง INSERT คือ INSERT INTO ชื่อตาราง (คอลัมน์ที่จะใส่) VALUES (ค่าที่จะใส่); ถ้ามีหลายแถว ก็ใส่คั่นด้วย comma (,) ได้เลย

จุดสังเกต 2 ข้อ:
- ไม่ได้ระบุคอลัมน์
idเพราะมันเป็นAUTO_INCREMENT— ฐานข้อมูลจะนับเลขให้เองอัตโนมัติ (1, 2, 3, …) province_idระบุเป็น รหัสจังหวัด (เช่น10) ไม่ใช่ชื่อจังหวัด เพราะมันเป็น Foreign Key ที่ชี้ไปที่province.code- ข้อความต้องอยู่ในเครื่องหมายคำพูด เช่น
'John','Male'ส่วนตัวเลขใส่ได้ตรง ๆ เช่น105.00 - วันที่ใช้รูปแบบ
YYYY-MM-DDเช่น'1985-03-15'คือ 15 มีนาคม 1985
6. SELECT — ดึงข้อมูล#
มาถึงหัวใจของบทความแล้ว SELECT เป็นคำสั่งที่ใช้บ่อยที่สุด เพราะส่วนใหญ่เราต้องการ “ดู” ข้อมูลมากกว่าเปลี่ยนแปลงมัน เปรียบเหมือนการถามฐานข้อมูลว่า “มีข้อมูลอะไรบ้าง บอกมาเลย”
6.1 รูปแบบพื้นฐาน#
SELECT column1, column2, ... -- อยากเห็นคอลัมน์อะไรบ้าง?
FROM table_name -- จากตารางไหน?
WHERE condition; -- (ไม่ใส่ก็ได้) เอาเฉพาะแถวที่ตรงเงื่อนไขsqlสังเกตว่าคำสั่งอ่านเป็นภาษาคนได้เลย: “เลือก (SELECT) คอลัมน์พวกนี้ จาก (FROM) ตารางนี้ โดยมีเงื่อนไขว่า (WHERE) …“
6.2 ทดสอบใน phpMyAdmin#
มาลองรันจริงกัน:
- เลือกฐานข้อมูล
testdbทางแผงด้านซ้าย แล้วคลิกตารางpatient - คลิกแท็บ SQL ด้านบนเพื่อเปิดช่องพิมพ์คำสั่ง
- พิมพ์คำสั่งนี้:
SELECT * FROM patient;sql
- คลิกปุ่ม Go ที่มุมขวาล่างเพื่อรัน
อธิบายคำสั่ง:
SELECT— บอกว่า “จะดึงข้อมูล”*(ดอกจัน) — หมายถึง “ทุกคอลัมน์” (เหมือนเครื่องหมายในคณิตศาสตร์ที่แปลว่า “คูณ” แต่ใน SQL ตอนอยู่หลัง SELECT แปลว่า “ทั้งหมด”)FROM patient— ดึงจากตารางpatient
ผลลัพธ์คือข้อมูลผู้ป่วยทั้ง 12 คน ทุกคอลัมน์:
ผลลัพธ์:
| id | title | fname | lname | gender | dob | province_id | weight | height |
|---|---|---|---|---|---|---|---|---|
| 1 | Mr. | John | Smith | Male | 1985-03-15 | 10 | 105.00 | 175.00 |
| 2 | Ms. | Mary | Johnson | Female | 1992-07-22 | 50 | 55.00 | 160.00 |
| 3 | Mr. | David | Lee | Male | 1988-11-30 | 10 | 112.00 | 178.00 |
| 4 | Mr. | Robert | Brown | Male | 1990-01-05 | 20 | 80.00 | 180.00 |
| 5 | Ms. | Linda | Wilson | Female | 1995-04-18 | 10 | 62.00 | 158.00 |
| 6 | Mr. | Michael | Davis | Male | 1983-09-12 | 50 | 120.00 | 175.00 |
| 7 | Ms. | Sarah | Miller | Female | 1998-06-25 | 10 | 48.00 | 155.00 |
| 8 | Mr. | James | Taylor | Male | 1987-12-08 | 20 | 75.00 | 172.00 |
| 9 | Ms. | Emily | Anderson | Female | 1993-02-14 | 50 | 58.00 | 165.00 |
| 10 | Mr. | Thomas | Thomas | Male | 1980-08-20 | 10 | 95.00 | 168.00 |
| 11 | Ms. | Jessica | Jackson | Female | 1996-10-03 | 10 | 70.00 | 170.00 |
| 12 | Mr. | Charles | White | Male | 1982-05-17 | 50 | 88.00 | 185.00 |
6.3 เลือกเฉพาะคอลัมน์ที่ต้องการ#
ถ้าไม่อยากเห็นทุกคอลัมน์ ก็ระบุชื่อคอลัมน์ที่ต้องการแทน * คั่นด้วย comma (,)
เลือกหนึ่งคอลัมน์:
SELECT fname FROM patient;sqlSELECT fname จะคืนเฉพาะคอลัมน์ชื่อ:
ผลลัพธ์:
| fname |
|---|
| John |
| Mary |
| David |
| Robert |
| Linda |
| Michael |
| Sarah |
| James |
| Emily |
| Thomas |
| Jessica |
| Charles |
เลือกหลายคอลัมน์:
SELECT fname, lname, dob FROM patient;sqlระบุชื่อคอลัมน์ 3 อัน คั่นด้วย comma (,) จะได้แค่ 3 คอลัมน์นั้น:
ผลลัพธ์:
| fname | lname | dob |
|---|---|---|
| John | Smith | 1985-03-15 |
| Mary | Johnson | 1992-07-22 |
| David | Lee | 1988-11-30 |
| Robert | Brown | 1990-01-05 |
| Linda | Wilson | 1995-04-18 |
| Michael | Davis | 1983-09-12 |
| Sarah | Miller | 1998-06-25 |
| James | Taylor | 1987-12-08 |
| Emily | Anderson | 1993-02-14 |
| Thomas | Thomas | 1980-08-20 |
| Jessica | Jackson | 1996-10-03 |
| Charles | White | 1982-05-17 |
เลือกทุกคอลัมน์:
SELECT * FROM patient;sqlSELECT * ให้ผลลัพธ์เหมือนตารางเต็มด้านบน (ทุกแถวและทุกคอลัมน์ รวม 12 record)
ทำไมไม่ใช้
*ตลอดไป? เพราะเวลาทำงานจริง ตารางอาจมีคอลัมน์เป็นสิบ ๆ คอลัมน์ การดึงมาทั้งหมดทำให้ช้าและยุ่งเหยิง การเลือกเฉพาะคอลัมน์ที่ใช้จะเร็วและอ่านง่ายกว่า ยิ่งถ้านำไปใช้ในแอปพลิเคชันจริง ยิ่งควรเลือกเฉพาะที่จำเป็น
🧩 แบบฝึกหัด 6.1: เขียน
SELECTให้แสดงเฉพาะคอลัมน์fname,genderและweightของผู้ป่วยทุกคน
7. WHERE — กรองข้อมูลด้วยเงื่อนไข#
WHERE (อ่านว่า “แวร์”) ใช้สำหรับ กรอง ให้แสดงเฉพาะแถวที่ตรงเงื่อนไขที่เรากำหนด เปรียบเหมือนตอนเราค้นหารายชื่อในสมุดโทรศัพท์ แล้วบอกว่า “เอาเฉพาะคนที่อยู่กรุงเทพฯ” คนอื่นจะถูกกรองออกหมด
ก่อนอื่นมาดูเครื่องหมายเปรียบเทียบที่ใช้ใน WHERE:
| เครื่องหมาย | ความหมาย | ตัวอย่าง |
|---|---|---|
= | เท่ากับ | gender = 'Male' |
<> หรือ != | ไม่เท่ากับ | gender <> 'Female' |
> | มากกว่า | weight > 100 |
< | น้อยกว่า | height < 160 |
>= | มากกว่าหรือเท่ากับ | weight >= 100 |
<= | น้อยกว่าหรือเท่ากับ | height <= 165 |
7.1 เงื่อนไขเดียว#
SELECT fname, lname, weight
FROM patient
WHERE weight > 100;sqlอ่านได้ว่า: “เลือกชื่อ นามสกุล น้ำหนัก จากตาราง patient โดยเอาเฉพาะคนที่ น้ำหนักมากกว่า 100” ผลคือเหลือเพียงคนที่น้ำหนัก 105, 112, 120 kg คนที่น้ำหนัก 100 หรือน้อยกว่าจะถูกตัดออก
ผลลัพธ์:
| fname | lname | weight |
|---|---|---|
| John | Smith | 105.00 |
| David | Lee | 112.00 |
| Michael | Davis | 120.00 |
7.2 เปรียบเทียบวันที่#
WHERE ใช้กับคอลัมน์ประเภทวันที่ (DATE) ได้ด้วย โดยเปรียบเทียบกับวันที่ในรูปแบบ YYYY-MM-DD (ต้องอยู่ในเครื่องหมายคำพูด) ตัวอย่างเช่น หาผู้ป่วยที่เกิดก่อนปี 1990:
SELECT fname, lname, dob
FROM patient
WHERE dob < '1990-01-01';sqlผลคือเหลือเฉพาะคนที่เกิดก่อนวันที่ 1990-01-01 ได้แก่ John, David, Michael, James, Charles และ Thomas ส่วนคนที่เกิดปี 1990 ขึ้นไปจะถูกตัดออก
ผลลัพธ์:
| fname | lname | dob |
|---|---|---|
| John | Smith | 1985-03-15 |
| David | Lee | 1988-11-30 |
| Michael | Davis | 1983-09-12 |
| James | Taylor | 1987-12-08 |
| Thomas | Thomas | 1980-08-20 |
| Charles | White | 1982-05-17 |
7.3 หลายเงื่อนไขด้วย AND / OR#
เราสามารถรวมหลายเงื่อนไขได้ด้วย AND (และ) และ OR (หรือ):
AND— ต้องเป็นจริง ทั้งสองเงื่อนไข (เหมือนบอกว่า “ต้องเป็น A และ B พร้อมกัน”)OR— พอเป็นจริง อย่างน้อยหนึ่งเงื่อนไข ก็พอ (เหมือนบอกว่า “เป็น A หรือ B ข้อใดข้อหนึ่งก็ได้”)
ตัวอย่าง AND — หาคนที่น้ำหนัก > 100 และ ส่วนสูง < 180 (ต้องครบทั้งสองข้อ):
SELECT fname, lname, weight, height
FROM patient
WHERE weight > 100 AND height < 180;sqlผลลัพธ์:
| fname | lname | weight | height |
|---|---|---|---|
| John | Smith | 105.00 | 175.00 |
| David | Lee | 112.00 | 178.00 |
| Michael | Davis | 120.00 | 175.00 |
ตัวอย่าง AND อีกกรณี — หาผู้ชายที่น้ำหนักมากกว่า 80:
SELECT *
FROM patient
WHERE gender = 'Male' AND weight > 80;sqlผลลัพธ์:
| id | title | fname | lname | gender | dob | province_id | weight | height |
|---|---|---|---|---|---|---|---|---|
| 1 | Mr. | John | Smith | Male | 1985-03-15 | 10 | 105.00 | 175.00 |
| 3 | Mr. | David | Lee | Male | 1988-11-30 | 10 | 112.00 | 178.00 |
| 6 | Mr. | Michael | Davis | Male | 1983-09-12 | 50 | 120.00 | 175.00 |
| 10 | Mr. | Thomas | Thomas | Male | 1980-08-20 | 10 | 95.00 | 168.00 |
| 12 | Mr. | Charles | White | Male | 1982-05-17 | 50 | 88.00 | 185.00 |
ตัวอย่าง OR — หา “ผู้ชายทั้งหมด” หรือ “คนที่น้ำหนักเกิน 60” (ใครตรงเงื่อนไขข้อใดข้อหนึ่งก็แสดง):
SELECT *
FROM patient
WHERE gender = 'Male' OR weight > 60;sqlผลลัพธ์ (ผู้ชายทุกคน บวกผู้หญิงที่น้ำหนักเกิน 60 คือ Linda และ Jessica):
| id | title | fname | lname | gender | dob | province_id | weight | height |
|---|---|---|---|---|---|---|---|---|
| 1 | Mr. | John | Smith | Male | 1985-03-15 | 10 | 105.00 | 175.00 |
| 3 | Mr. | David | Lee | Male | 1988-11-30 | 10 | 112.00 | 178.00 |
| 4 | Mr. | Robert | Brown | Male | 1990-01-05 | 20 | 80.00 | 180.00 |
| 5 | Ms. | Linda | Wilson | Female | 1995-04-18 | 10 | 62.00 | 158.00 |
| 6 | Mr. | Michael | Davis | Male | 1983-09-12 | 50 | 120.00 | 175.00 |
| 8 | Mr. | James | Taylor | Male | 1987-12-08 | 20 | 75.00 | 172.00 |
| 10 | Mr. | Thomas | Thomas | Male | 1980-08-20 | 10 | 95.00 | 168.00 |
| 11 | Ms. | Jessica | Jackson | Female | 1996-10-03 | 10 | 70.00 | 170.00 |
| 12 | Mr. | Charles | White | Male | 1982-05-17 | 50 | 88.00 | 185.00 |
จุดที่มือใหม่พลาดบ่อย:
- ข้อความต้องใส่เครื่องหมายคำพูด เช่น
gender = 'Male'(ถ้าลืมจะ error)- ตัวเลข ไม่ ต้องใส่เครื่องหมายคำพูด เช่น
weight > 60- วันที่ต้องใช้รูปแบบ
YYYY-MM-DDเท่านั้น และต้องอยู่ในเครื่องหมายคำพูด เช่น'1990-01-01'
🧩 แบบฝึกหัด 7.1: เขียน query หาผู้ป่วยที่อยู่จังหวัด Bangkok (
province_id = 10) แสดงชื่อและนามสกุล
8. ORDER BY — เรียงลำดับผลลัพธ์#
ปกติผลลัพธ์ที่ได้จาก SELECT อาจวางในลำดับที่คาดเดาไม่ได้ ORDER BY ช่วย เรียงลำดับ ข้อมูลตามคอลัมน์ที่เราเลือก เปรียบเหมือนตอนเราจัดระเบียบรายชื่อนักเรียนตามเลขที่ หรือเรียงคะแนนสอบจากสูงไปต่ำ
8.1 รูปแบบพื้นฐาน#
SELECT column1, column2, ...
FROM table_name
ORDER BY column1 ASC|DESC;sqlASC(Ascending) — น้อยไปมาก / A ไป Z (ถ้าไม่ระบุ จะเป็นASCโดยค่าเริ่มต้น)DESC(Descending) — มากไปน้อย / Z ไป A
8.2 ตัวอย่าง: เรียงตามน้ำหนักจากมากไปน้อย#
SELECT fname, lname, weight, height
FROM patient
WHERE weight > 100 AND height < 180
ORDER BY weight DESC;sqlQuery นี้กรองเอาคนที่น้ำหนัก > 100 และส่วนสูง < 180 ก่อน แล้วจัดเรียงตามน้ำหนักจากมากไปน้อย (DESC) คนที่หนักที่สุดจะอยู่บนสุด:
ผลลัพธ์ (เรียงจากน้ำหนักมากไปน้อย):
| fname | lname | weight | height |
|---|---|---|---|
| Michael | Davis | 120.00 | 175.00 |
| David | Lee | 112.00 | 178.00 |
| John | Smith | 105.00 | 175.00 |
8.3 ตัวอย่าง: เรียงตามวันเกิด (อายุ)#
SELECT fname, lname, dob
FROM patient
ORDER BY dob DESC;sqlเทคนิคเรื่องวันที่: ค่าวันที่ที่ “ใหญ่กว่า” คือวันที่ที่ “ช้ากว่า” (ใหม่กว่า = อายุน้อยกว่า) ดังนั้น
ORDER BY dob DESC(มากไปน้อย) จะเรียงจากอายุน้อยไปมาก — คนอายุน้อยที่สุดอยู่บนสุด หากอยากได้จากอายุมากไปน้อย ก็เปลี่ยนเป็นORDER BY dob ASC
ผลลัพธ์ (วันเกิดใหม่สุด/อายุน้อยสุดอยู่บนสุด):
| fname | lname | dob |
|---|---|---|
| Sarah | Miller | 1998-06-25 |
| Jessica | Jackson | 1996-10-03 |
| Linda | Wilson | 1995-04-18 |
| Emily | Anderson | 1993-02-14 |
| Mary | Johnson | 1992-07-22 |
| Robert | Brown | 1990-01-05 |
| David | Lee | 1988-11-30 |
| James | Taylor | 1987-12-08 |
| John | Smith | 1985-03-15 |
| Michael | Davis | 1983-09-12 |
| Charles | White | 1982-05-17 |
| Thomas | Thomas | 1980-08-20 |
8.4 เรียงหลายคอลัมน์#
เราสามารถเรียงตามมากกว่าหนึ่งคอลัมน์ได้ โดยระบุเป็นลำดับชั้น — เรียงตามคอลัมน์แรกก่อน แล้วในแต่ละกลุ่มค่อยเรียงตามคอลัมน์ที่สอง
SELECT fname, lname, gender, weight
FROM patient
ORDER BY gender ASC, weight DESC;sqlคำสั่งนี้สั่งให้: เรียงตามเพศจาก A ไป Z ก่อน (Female ก่อน Male) แล้ว ภายใน แต่ละเพศ ค่อยเรียงน้ำหนักจากมากไปน้อย:
ผลลัพธ์ (เพศ A→Z แล้วเรียงน้ำหนักมาก→น้อยในแต่ละเพศ):
| fname | lname | gender | weight |
|---|---|---|---|
| Jessica | Jackson | Female | 70.00 |
| Linda | Wilson | Female | 62.00 |
| Emily | Anderson | Female | 58.00 |
| Mary | Johnson | Female | 55.00 |
| Sarah | Miller | Female | 48.00 |
| Michael | Davis | Male | 120.00 |
| David | Lee | Male | 112.00 |
| John | Smith | Male | 105.00 |
| Thomas | Thomas | Male | 95.00 |
| Charles | White | Male | 88.00 |
| Robert | Brown | Male | 80.00 |
| James | Taylor | Male | 75.00 |
การเรียงหลายคอลัมน์มีประโยชน์มากสำหรับรายงาน เช่น อยากเห็นนักเรียนแยกตามห้อง แล้วในแต่ละห้องเรียงตามคะแนนสอบ
🧩 แบบฝึกหัด 8.1: เรียงผู้ป่วยตามส่วนสูงจากมากไปน้อย แสดงชื่อและส่วนสูง
9. คำนวณใน query — คอลัมน์คำนวณ (Calculated Columns)#
นอกจากจะดึงคอลัมน์ที่มีอยู่แล้ว SQL ยัง คำนวณค่าใหม่ได้ในตัว ด้วยเครื่องหมายทางคณิตศาสตร์ + - * / แล้วตั้งชื่อให้คอลัมน์ผลลัพธ์ด้วย AS เปรียบเหมือนการใส่ “สูตร” ใน Excel ที่คำนวณค่าใหม่จากคอลัมน์เดิม
ผลลัพธ์ที่คำนวณได้นี้เรียกว่า คอลัมน์คำนวณ (calculated column) — มันไม่ได้ถูกเก็บในตารางจริง แต่เกิดขึ้นตอนรัน query เท่านั้น
9.1 ตัวอย่าง: คำนวณ BMI ของผู้ป่วยแต่ละคน#
BMI (Body Mass Index — ดัชนีมวลกาย) คำนวณจากสูตร น้ำหนัก(kg) / (ส่วนสูงเป็นเมตร)² ปัญหาคือในตารางเราเก็บส่วนสูงเป็น เซนติเมตร (เช่น 175) จึงต้องหาร 100 ให้กลายเป็นเมตร (1.75) ก่อน
SELECT fname,
lname,
weight,
height,
weight / ((height / 100) * (height / 100)) AS BMI
FROM patient;sqlอธิบายสูตรทีละชั้น:
height / 100— แปลงเซนติเมตรเป็นเมตร (เช่น 175 → 1.75)(height / 100) * (height / 100)— ส่วนสูงเป็นเมตร ยกกำลังสอง (เมตร²)weight / (...)— เอาน้ำหนักหารด้วยเมตร² ได้ BMIAS BMI— ตั้งชื่อให้คอลัมน์ผลลัพธ์นี้ว่าBMI(ถ้าไม่ตั้งชื่อ จะขึ้นเป็นสูตรยาว ๆ ดูไม่สวย)
ผลลัพธ์:
| fname | lname | weight | height | BMI |
|---|---|---|---|---|
| John | Smith | 105.00 | 175.00 | 34.29 |
| Mary | Johnson | 55.00 | 160.00 | 21.48 |
| David | Lee | 112.00 | 178.00 | 35.35 |
| Robert | Brown | 80.00 | 180.00 | 24.69 |
| Linda | Wilson | 62.00 | 158.00 | 24.84 |
| Michael | Davis | 120.00 | 175.00 | 39.18 |
| Sarah | Miller | 48.00 | 155.00 | 19.98 |
| James | Taylor | 75.00 | 172.00 | 25.35 |
| Emily | Anderson | 58.00 | 165.00 | 21.30 |
| Thomas | Thomas | 95.00 | 168.00 | 33.66 |
| Jessica | Jackson | 70.00 | 170.00 | 24.22 |
| Charles | White | 88.00 | 185.00 | 25.71 |
ทำไมไม่เก็บคอลัมน์ BMI ไว้ในตารางเลย? เพราะถ้าเก็บไว้ วันที่น้ำหนักเปลี่ยน เราต้องมานั่งอัปเดต BMI ใหม่เอง — ลืมทีเดียวข้อมูลก็ผิด การคำนวณใน query แบบนี้จึงประหยัดพื้นที่และไม่มีโอกาสข้อมูลไม่ตรงกัน
ต่อไป: เราจะเอา BMI ที่คำนวณได้นี้ไปใช้กับ
GROUP BYเพื่อหา BMI เฉลี่ยแยกตามเพศ (หัวข้อถัดไป)
🧩 แบบฝึกหัด 9.1: แสดงน้ำหนักของผู้ป่วยเป็นปอนด์ (kg × 2.20462) ตั้งชื่อคอลัมน์ผลลัพธ์ว่า
weight_lbs
10. GROUP BY — จัดกลุ่มและสรุปข้อมูล#
GROUP BY ใช้สำหรับ จัดกลุ่ม แถวที่มีค่าเดียวกันเข้าด้วยกัน แล้ว สรุป แต่ละกลุ่มด้วยฟังก์ชันพิเศษ เปรียบเหมือนตอนคุณครูแบ่งนักเรียนตามห้อง แล้วนับว่าแต่ละห้องมีกี่คน หรือหาคะแนนเฉลี่ยของแต่ละห้อง
ฟังก์ชันสรุปที่ใช้บ่อย (เรียกว่า aggregate function) มีดังนี้:
| ฟังก์ชัน | ทำหน้าที่ | เช่น |
|---|---|---|
COUNT() | นับจำนวนแถว | มีผู้ป่วยกี่คน |
SUM() | หาผลรวม | น้ำหนักรวมทั้งหมด |
AVG() | หาค่าเฉลี่ย | น้ำหนักเฉลี่ย |
MAX() | หาค่ามากที่สุด | น้ำหนักมากสุด |
MIN() | หาค่าน้อยที่สุด | น้ำหนักน้อยสุด |
10.1 รูปแบบพื้นฐาน#
SELECT column1, aggregate_function(column2)
FROM table_name
GROUP BY column1;sql10.2 ตัวอย่าง: หาค่าเฉลี่ยน้ำหนักและส่วนสูงแยกตามเพศ#
SELECT gender, AVG(weight), AVG(height)
FROM patient
GROUP BY gender;sqlฐานข้อมูลจะ แบ่ง ผู้ป่วยออกเป็นกลุ่มตามเพศ (Male / Female) แล้ว คำนวณ AVG() ของแต่ละกลุ่มแยกกัน ผลคือมี record สรุปหนึ่งบรรทัดต่อเพศ:
ผลลัพธ์:
| gender | AVG(weight) | AVG(height) |
|---|---|---|
| Male | 96.43 | 176.14 |
| Female | 58.60 | 161.60 |
อ่านผลได้ว่า ผู้ชาย 7 คน มีน้ำหนักเฉลี่ย 96.43 kg ส่วนสูงเฉลี่ย 176.14 cm ส่วนผู้หญิง 5 คน น้ำหนักเฉลี่ย 58.60 kg ส่วนสูงเฉลี่ย 161.60 cm
10.3 Aggregate Function อื่น ๆ#
เปลี่ยนฟังก์ชันสรุปดู — ทั้ง 4 คำสั่งนี้ให้ผล 2 บรรทัด (Male และ Female) เหมือนกัน แต่สรุปต่างกัน
COUNT(*) — นับจำนวนผู้ป่วยในแต่ละเพศ:
SELECT gender, COUNT(*) FROM patient GROUP BY gender;sqlผลลัพธ์:
| gender | COUNT(*) |
|---|---|
| Male | 7 |
| Female | 5 |
SUM(weight) — ผลรวมน้ำหนักในแต่ละเพศ:
SELECT gender, SUM(weight) FROM patient GROUP BY gender;sqlผลลัพธ์:
| gender | SUM(weight) |
|---|---|
| Male | 675.00 |
| Female | 293.00 |
MAX(weight) — น้ำหนักสูงสุดในแต่ละเพศ:
SELECT gender, MAX(weight) FROM patient GROUP BY gender;sqlผลลัพธ์:
| gender | MAX(weight) |
|---|---|
| Male | 120.00 |
| Female | 70.00 |
MIN(weight) — น้ำหนักต่ำสุดในแต่ละเพศ:
SELECT gender, MIN(weight) FROM patient GROUP BY gender;sqlผลลัพธ์:
| gender | MIN(weight) |
|---|---|
| Male | 75.00 |
| Female | 48.00 |
10.4 คำนวณก่อนสรุป: หาค่าเฉลี่ย BMI แยกตามเพศ#
เราสามารถเอาสูตรคำนวณ BMI (จากหัวข้อก่อน) ไปห่อไว้ใน AVG() ได้เลย เพื่อหา BMI เฉลี่ยของแต่ละเพศ
SELECT gender,
AVG(weight / ((height / 100) * (height / 100))) AS BMI
FROM patient
GROUP BY gender;sqlลำดับการทำงานในใจได้ดังนี้:
- SQL คำนวณ BMI ให้ผู้ป่วยทุกคนก่อน (จาก
weightและheight) - แยกคนออกเป็นกลุ่มตามเพศ
AVG()หาค่าเฉลี่ย BMI ของแต่ละกลุ่มAS BMIตั้งชื่อคอลัมน์ผลลัพธ์ว่าBMI
ผลลัพธ์:
| gender | BMI |
|---|---|
| Male | 31.18 |
| Female | 22.37 |
ผู้ชายมี BMI เฉลี่ยสูงกว่าผู้หญิง (สอดคล้องกับน้ำหนักเฉลี่ยที่มากกว่า)
10.5 ใช้กับวันที่: หาอายุมาก/น้อยที่สุดในแต่ละเพศ#
MIN() และ MAX() ใช้กับวันที่ได้ด้วย เช่น หาวันเกิดเก่าที่สุด (อายุมากที่สุด) และใหม่ที่สุด (อายุน้อยที่สุด) ของผู้ป่วยในแต่ละเพศ:
SELECT gender,
MIN(dob) AS oldest,
MAX(dob) AS youngest
FROM patient
GROUP BY gender;sqlผลลัพธ์:
| gender | oldest | youngest |
|---|---|---|
| Male | 1980-08-20 | 1990-01-05 |
| Female | 1992-07-22 | 1998-06-25 |
MIN(dob)— วันเกิดที่เก่าที่สุด (อายุมากที่สุด) ในกลุ่ม เช่น ผู้ชายคือ1980-08-20MAX(dob)— วันเกิดที่ใหม่ที่สุด (อายุน้อยที่สุด) ในกลุ่ม เช่น ผู้หญิงคือ1998-06-25
เคล็ดลับ: ใช้
ASตั้งชื่อให้คอลัมน์ผลลัพธ์ (เช่นoldest,youngest) จะทำให้ตารางผลลัพธ์อ่านเข้าใจง่ายขึ้นมาก
การประยุกต์ใช้จริง: นับผู้ป่วยตามจังหวัด, หา BMI เฉลี่ยตามเพศ, นับคำสั่งซื้อตามลูกค้า, คำนวณยอดขายรวมตามหมวดสินค้า, นับนักศึกษาตามคณะ
🧩 แบบฝึกหัด 10.1: นับจำนวนผู้ป่วยในแต่ละจังหวัด โดยจัดกลุ่มตาม
province_id
11. JOIN — เชื่อมหลายตารางเข้าด้วยกัน#
ในฐานข้อมูลจริง ข้อมูลมักถูกแบ่งเก็บในหลายตารางเพื่อลดความซ้ำซ้อน ในตัวอย่างของเรา ตาราง patient เก็บแค่ “รหัสจังหวัด” (province_id) ส่วน “ชื่อจังหวัด” เก็บแยกในตาราง province เมื่อเราอยากเห็นทั้งชื่อผู้ป่วยและชื่อจังหวัดพร้อมกัน ต้องใช้ JOIN เพื่อ เชื่อม สองตารางเข้าด้วยกัน
เปรียบเหมือนฟังก์ชัน VLOOKUP ใน Excel — เอาค่าจากตารางหนึ่งไป “ค้นหา” ในอีกตารางเพื่อดึงข้อมูลที่เกี่ยวข้องมาแสดง
11.1 LEFT JOIN#
มีหลายชนิดของ JOIN แต่ที่ใช้บ่อยที่สุดคือ LEFT JOIN ซึ่งคืน:
- ทุกแถวจากตารางด้านซ้าย (ตารางที่เขียนหลัง FROM)
- บวกข้อมูลที่ตรงกันจากตารางด้านขวา (ตารางที่เขียนหลัง LEFT JOIN)
- ถ้าตารางด้านขวาไม่มีข้อมูลที่ตรง คอลัมน์ของตารางด้านขวาจะเป็น
NULL(ค่าว่าง)
11.2 รูปแบบพื้นฐาน#
SELECT column1, column2, ...
FROM table1
LEFT JOIN table2
ON table1.column = table2.column;sqlบรรทัด ON สำคัญมาก — มันบอกว่า “จับคู่สองตารางด้วยคอลัมน์ไหน” ในที่นี้คือจับคู่ province_id ของผู้ป่วยกับ code ของจังหวัด
11.3 ตัวอย่าง: แสดงชื่อจังหวัดของผู้ป่วย#
SELECT patient.id,
patient.fname,
patient.dob,
patient.province_id,
province.name
FROM patient
LEFT JOIN province
ON patient.province_id = province.code;sqlอธิบายทีละส่วน:
FROM patient— ตารางpatientเป็น ตารางด้านซ้าย (เราต้องการเห็นผู้ป่วยทุกคน)LEFT JOIN province— เอาตารางprovinceมาแปะข้าง (ตารางด้านขวา)ON patient.province_id = province.code— จับคู่โดยดูว่าprovince_idของผู้ป่วยตรงกับcodeของจังหวัดไหน
ผลลัพธ์:
| id | fname | dob | province_id | name |
|---|---|---|---|---|
| 1 | John | 1985-03-15 | 10 | Bangkok |
| 2 | Mary | 1992-07-22 | 50 | Chiang Mai |
| 3 | David | 1988-11-30 | 10 | Bangkok |
| 4 | Robert | 1990-01-05 | 20 | Nakhon Ratchasima |
| 5 | Linda | 1995-04-18 | 10 | Bangkok |
| 6 | Michael | 1983-09-12 | 50 | Chiang Mai |
| 7 | Sarah | 1998-06-25 | 10 | Bangkok |
| 8 | James | 1987-12-08 | 20 | Nakhon Ratchasima |
| 9 | Emily | 1993-02-14 | 50 | Chiang Mai |
| 10 | Thomas | 1980-08-20 | 10 | Bangkok |
| 11 | Jessica | 1996-10-03 | 10 | Bangkok |
| 12 | Charles | 1982-05-17 | 50 | Chiang Mai |
สังเกตคอลัมน์สุดท้าย name — เดิมทีตาราง patient ไม่มีคอลัมน์นี้ แต่พอ JOIN กับตาราง province เราก็ดึงชื่อจังหวัดมาแสดงได้ เช่น province_id 10 → Bangkok, 50 → Chiang Mai
ถ้าจังหวัดไม่มีในตาราง
provinceจะเป็นอย่างไร? ผู้ป่วยจะยังแสดง (เพราะเป็น LEFT JOIN เก็บตารางซ้ายครบ) แต่คอลัมน์ชื่อจังหวัดจะเป็นNULL
11.4 ใช้ Table Alias ให้ query สั้นและอ่านง่ายขึ้น#
สังเกตว่าข้างบนเราต้องพิมพ์ patient.id, patient.fname … ซ้ำ ๆ ยาว ๆ SQL อนุญาตให้ตั้ง ชื่อย่อ (table alias) ให้ตารางได้ เพื่อให้พิมพ์สั้นลง
SELECT p.id,
p.fname,
p.dob,
p.province_id,
pr.name
FROM patient p
LEFT JOIN province pr
ON p.province_id = pr.code;sqlpatient p— ตั้งชื่อย่อตารางpatientว่าpprovince pr— ตั้งชื่อย่อตารางprovinceว่าpr
จากนั้นเขียน p.id แทน patient.id ได้เลย ผลลัพธ์เหมือนเดิมทุกประการ (12 แถวเดียวกัน) — alias เป็นแค่ชื่อเรียก ไม่เปลี่ยนผลลัพธ์ แต่ทำให้ query สั้นและอ่านง่ายขึ้นมาก โดยเฉพาะเวลา JOIN หลายตาราง
🧩 แบบฝึกหัด 11.1: เขียน query แสดงชื่อผู้ป่วยและชื่อจังหวัด โดยใช้ table alias
pสำหรับpatientและprสำหรับprovince
12. INSERT — เพิ่มข้อมูล#
จริง ๆ เราเคยใช้ INSERT ไปแล้วในหัวข้อ 5 (ตอนใส่ข้อมูลตัวอย่าง) คราวนี้มาดูรูปแบบให้ละเอียด INSERT ใช้สำหรับ เพิ่มแถวใหม่ เข้าตาราง ต่างจาก UPDATE (แก้ข้อมูลเดิม) และ DELETE (ลบข้อมูล)
12.1 รูปแบบพื้นฐาน#
INSERT INTO table_name (column1, column2, ...)
VALUES (value1, value2, ...);sql- จำนวน value ต้องเท่ากับจำนวน column และ ลำดับต้องตรงกัน
- ข้อความต้องอยู่ในเครื่องหมายคำพูด เช่น
'Somchai'ส่วนตัวเลขใส่ตรง ๆ เช่น78.00
12.2 เพิ่มแถวเดียว (Single)#
เพิ่มผู้ป่วยใหม่ 1 คน:
INSERT INTO patient (title, fname, lname, gender, dob, province_id, weight, height)
VALUES ('Mr.', 'Somchai', 'Jaidee', 'Male', '1990-01-01', 10, 78.00, 175.00);sqlไม่ต้องระบุ id เพราะมันเป็น AUTO_INCREMENT — ฐานข้อมูลจะนับให้เอง (ผู้ป่วยคนต่อไปจะได้ id = 13) ส่วน province_id = 10 หมายถึงกรุงเทพฯ ซึ่งต้องเป็น code ที่มีอยู่ในตาราง province
12.3 เพิ่มหลายแถว (Multiple)#
ถ้าจะเพิ่มหลายคน ไม่ต้องเขียน INSERT ทีละบรรทัด — คั่นแต่ละชุดค่าด้วย comma (,) ได้เลย (เหมือนที่ใช้ในหัวข้อ 5):
INSERT INTO patient (title, fname, lname, gender, dob, province_id, weight, height) VALUES
('Ms.', 'Naree', 'Phromma', 'Female', '1995-05-20', 30, 52.00, 162.00),
('Ms.', 'Ploy', 'Srisuwan', 'Female', '1997-03-10', 30, 50.00, 160.00);sqlคำสั่งเดียวเพิ่มได้ 2 คนพร้อมกัน คือ Naree (id=14) และ Ploy (id=15)
เกร็ด: เราตั้ง
province_id = 30(Nakhon Pathom) ให้ Naree และ Ploy เพราะในข้อมูลตัวอย่างเดิม ไม่มีผู้ป่วยคนไหนอยู่จังหวัด 30 เลย ทำให้หัวข้อUPDATEและDELETEถัดไปใช้WHERE province_id = 30เลือกเฉพาะคนที่เราเพิ่งเพิ่มนี้ได้สะดวก โดยไม่ไปกระทบข้อมูล 12 คนเดิม
เคล็ดลับ: การเพิ่มหลายแถวในคำสั่งเดียว (multiple-row INSERT) เร็วกว่ารัน
INSERTทีละแถวหลายครั้ง โดยเฉพาะตอนโหลดข้อมูลจำนวนมาก
🧩 แบบฝึกหัด 12.1: เพิ่มผู้ป่วยใหม่ 1 คนโดยใช้ข้อมูลของคุณเอง (อย่าลืมว่า
province_idต้องเป็นcodeที่มีในตารางprovince)
13. UPDATE — แก้ไขข้อมูล#
UPDATE (อ่านว่า “อัปเดต”) ใช้สำหรับ แก้ไขข้อมูลที่มีอยู่แล้ว ในตาราง ต่างจาก INSERT ที่เพิ่มแถวใหม่ UPDATE เปรียบเหมือนการใช้ยาลบคำแก้ข้อมูลในสมุดบัญชี — ไม่ได้เพิ่มหน้าใหม่ แต่ไปแก้สิ่งที่เขียนไว้แล้ว
13.1 รูปแบบพื้นฐาน#
UPDATE table_name
SET column1 = value1,
column2 = value2
WHERE condition;sqlUPDATE ชื่อตาราง— บอกว่าจะแก้ตารางไหนSET คอลัมน์ = ค่าใหม่— กำหนดค่าใหม่ให้คอลัมน์ (ถ้าหลายคอลัมน์ คั่นด้วย comma (,))WHERE เงื่อนไข— เลือกว่าจะแก้แถวไหน (สำคัญมาก! จะอธิบายต่อ)
13.2 แก้แถวเดียว (Single)#
ตัวอย่าง: แก้น้ำหนักของผู้ป่วย Somchai (id = 13 — คนที่เราเพิ่งเพิ่มในหัวข้อ INSERT) จาก 78.00 เป็น 80.00:
UPDATE patient
SET weight = 80
WHERE id = 13;sqlอ่านได้ว่า: “อัปเดตตาราง patient ตั้ง น้ำหนักเป็น 80 โดยเอาเฉพาะ แถวที่ id = 13” ผลคือค่า weight ของ Somchai เปลี่ยนไป:
ก่อน:
| id | fname | weight |
|---|---|---|
| 13 | Somchai | 78.00 |
หลัง:
| id | fname | weight |
|---|---|---|
| 13 | Somchai | 80.00 |
เทคนิค: แก้เสร็จแล้ว เรามักใช้
SELECT * FROM patient WHERE id = 13;ตรวจสอบว่าข้อมูลเปลี่ยนจริงหรือไม่ เพราะUPDATEไม่ได้คืนตารางผลลัพธ์ให้ดู
13.3 แก้หลายคอลัมน์พร้อมกัน#
อยากแก้ทั้งน้ำหนักและส่วนสูงในคำสั่งเดียว ให้คั่นแต่ละ คอลัมน์ = ค่า ด้วย comma (,):
UPDATE patient
SET weight = 80,
height = 180
WHERE id = 13;sqlคราวนี้ Somchai จะมีน้ำหนัก 80 และส่วนสูง 180 พร้อมกัน
13.4 แก้หลายแถว (Multiple)#
ถ้าเงื่อนไข WHERE ตรงกับหลายแถว UPDATE จะแก้ครบทุกแถวที่ตรง ตัวอย่าง: แก้น้ำหนักของผู้ป่วยที่เราเพิ่งเพิ่ม (Naree และ Ploy ที่อยู่ province_id = 30) ทั้งคู่เป็น 60.00:
UPDATE patient
SET weight = 60
WHERE province_id = 30;sqlคำสั่งนี้จะแก้ทุกแถวที่ province_id = 30 ซึ่งมี 2 คน (Naree id=14 และ Ploy id=15):
ก่อน:
| id | fname | weight |
|---|---|---|
| 14 | Naree | 52.00 |
| 15 | Ploy | 50.00 |
หลัง:
| id | fname | weight |
|---|---|---|
| 14 | Naree | 60.00 |
| 15 | Ploy | 60.00 |
⚠️ คำเตือนสำคัญ: หากลืมใส่
WHEREฐานข้อมูลจะแก้ ทุกแถว ในตาราง!sqlUPDATE patient SET weight = 80; -- ทุกคนจะมีน้ำหนัก 80 ทันทีส่วนใหญ่ไม่ใช่สิ่งที่ตั้งใจ ให้ตรวจ
WHEREเสมอก่อนกดรันUPDATE
🧩 แบบฝึกหัด 13.1: แก้ส่วนสูงของผู้ป่วย Somchai (
id = 13) จาก 175.00 เป็น 178.00
14. DELETE — ลบข้อมูล#
DELETE (อ่านว่า “ดีลีต”) ใช้สำหรับ ลบแถวออกจากตารางอย่างถาวร ต่างจาก UPDATE ที่แค่แก้ข้อมูล DELETE คือการ “ลบทิ้ง” ไปเลย จึงต้องใช้อย่างระมัดระวัง เพราะข้อมูลที่ลบแล้วกู้คืนยาก
14.1 รูปแบบพื้นฐาน#
DELETE FROM table_name
WHERE condition;sqlสังเกตว่า DELETE ไม่มีชื่อคอลัมน์ — เพราะมันลบทั้งแถว ไม่ใช่ลบเฉพาะคอลัมน์
14.2 ลบแถวเดียว (Single)#
ตัวอย่าง: ลบผู้ป่วย Somchai (id = 13 — คนที่เราเพิ่งเพิ่ม) ออกจากตาราง:
DELETE FROM patient
WHERE id = 13;sqlหลังรัน แถวของ Somchai จะหายไปจากตาราง patient ส่วนแถวอื่นยังอยู่ครบ
14.3 ลบหลายแถว (Multiple)#
ถ้า WHERE ตรงกับหลายแถว ก็จะลบครบทุกแถวนั้น ตัวอย่าง: ลบผู้ป่วยที่เราเพิ่งเพิ่ม (Naree และ Ploy ที่อยู่ province_id = 30):
DELETE FROM patient
WHERE province_id = 30;sqlคำสั่งนี้จะลบ 2 แถว คือ Naree (id=14) และ Ploy (id=15) — ผู้ป่วยที่เราเพิ่งเพิ่มในหัวข้อ INSERT
⚠️ คำเตือนสำคัญ: หากลืมใส่
WHEREจะเป็นการลบ ทุกแถว ในตาราง!sqlDELETE FROM patient; -- ลบข้อมูลทุกแถว! โครงสร้างตารางยังอยู่ แต่ข้อมูลหายหมดให้ตรวจ
WHEREเสมอก่อนกดรันDELETE
เกร็ด: หลัง
DELETEตารางยังอยู่ (โครงสร้างคอลัมน์ไม่หาย) เพียงแต่ข้อมูลในนั้นถูกลบไป หากต้องการลบทั้งตารางทั้งโครงสร้าง+ข้อมูล ใช้คำสั่งDROP TABLE patient;แต่ใช้น้อยและอันตราย ระวังให้ดี
🧩 แบบฝึกหัด 14.1: ลองเพิ่มผู้ป่วยใหม่ 1 คน (ด้วย
INSERT) แล้วลบออกด้วยDELETE— สังเกตว่าหลังลบแล้วแถวนั้นหายไป
15. สรุป#
ขอแสดงความยินดีด้วย คุณได้เรียนรู้คำสั่ง SELECT และส่วนประกอบต่าง ๆ ที่ใช้ดึงและจัดการผลลัพธ์ครบแล้ว มาทบทวนกัน:
SELECT— เลือกคอลัมน์ที่จะแสดง (SELECT *คือทุกคอลัมน์)WHERE— กรองเฉพาะแถวที่ตรงเงื่อนไข รองรับAND/ORและการเปรียบเทียบทั้งตัวเลขและวันที่ORDER BY— เรียงลำดับผลลัพธ์ (ASCน้อยไปมาก /DESCมากไปน้อย) ได้หลายคอลัมน์- คอลัมน์คำนวณ — คำนวณค่าใหม่ใน query ด้วย
+ - * /แล้วตั้งชื่อด้วยAS(เช่น BMI) GROUP BY— จัดกลุ่มแล้วสรุปด้วย aggregate function (COUNT,SUM,AVG,MIN,MAX)JOIN— เชื่อมหลายตารางเข้าด้วยกัน เช่นLEFT JOINพร้อมใช้ table alias ให้สั้นลงINSERT— เพิ่มแถวใหม่เข้าตาราง ทั้งทีละแถวและหลายแถวในคำสั่งเดียวUPDATE— แก้ไขข้อมูลที่มีอยู่ ทั้งแถวเดียวและหลายแถว (อย่าลืมWHEREไม่งั้นจะแก้ทุกแถว)DELETE— ลบแถวออกจากตารางอย่างถาวร (อย่าลืมWHEREไม่งั้นจะลบทุกแถว)
ลองนึกถึงคำสั่งเหล่านี้เป็น “ประโยค” ที่เราใช้ถามฐานข้อมูล:
“เลือก (SELECT) ชื่อและน้ำหนัก จาก (FROM) ตารางผู้ป่วย โดยเอาเฉพาะ (WHERE) คนที่น้ำหนักเกิน 100 แล้วเรียง (ORDER BY) จากมากไปน้อย”
เมื่อเข้าใจ SELECT และส่วนประกอบเหล่านี้แล้ว คุณสามารถดึงและวิเคราะห์ข้อมูลจากฐานข้อมูลได้อย่างมีประสิทธิภาพ พร้อมต่อยอดสู่การทำ report, analytics และการพัฒนาแอปพลิเคชันที่เชื่อมต่อฐานข้อมูลต่อไป