บทความนี้คือจุดเริ่มต้นสำหรับผู้ที่อยากเข้าใจ Relational Database และภาษา SQL ตั้งแต่แนวคิดของระบบจัดการฐานข้อมูล โครงสร้างตาราง ความสัมพันธ์ระหว่างตารางผ่าน Primary Key และ Foreign Key ไปจนถึงการเขียน SQL คำสั่งสำคัญ
1. รู้จักกับ Database Management System (DBMS)#
DBMS (Database Management System) คือซอฟต์แวร์ที่ใช้สำหรับสร้าง จัดการ และควบคุมฐานข้อมูล ทำหน้าที่เป็นตัวกลางเชื่อมระหว่างผู้ใช้ แอปพลิเคชัน และข้อมูลที่จัดเก็บอยู่ในฐานข้อมูล ตัวอย่าง DBMS ที่นิยมได้แก่ MySQL, PostgreSQL, Microsoft SQL Server และ Oracle Database

DBMS ช่วยให้องค์กรจัดการข้อมูลได้ครบทั้ง 4 มิติหลัก ได้แก่
สร้างและจัดการฐานข้อมูล#
DBMS ช่วยให้เราสร้างและจัดระเบียบฐานข้อมูลได้อย่างมีประสิทธิภาพ ผู้ใช้สามารถสร้างตาราง เพิ่มข้อมูล แก้ไขข้อมูล และลบข้อมูลที่ไม่ต้องการได้ ตัวอย่างเช่น ระบบโรงพยาบาลอาจเก็บข้อมูลผู้ป่วยไว้ในตาราง patient และข้อมูลจังหวัดไว้ในตาราง province ทำให้การจัดการข้อมูลเป็นระบบและเชื่อถือได้มากขึ้น
ควบคุมการเข้าถึงข้อมูล (Access Control)#
DBMS จัดการสิทธิ์ (permission) และระดับการเข้าถึงของผู้ใช้แต่ละคน ผู้ใช้คนละคนสามารถมีสิทธิ์เข้าถึงฐานข้อมูลเดียวกันในระดับที่ต่างกันได้ ตัวอย่างเช่น แพทย์สามารถแก้ไขประวัติผู้ป่วยได้ ในขณะที่เจ้าหน้าที่ต้อนรับสามารถ “ดู” ข้อมูลผู้ป่วยได้อย่างเดียว ซึ่งช่วยปกป้องข้อมูลที่ละเอียดอ่อนจากการเปลี่ยนแปลงโดยไม่ได้รับอนุญาต
สำรองและกู้คืนข้อมูล (Backup & Recovery)#
DBMS มีกลไกสำรองข้อมูล (backup) และกู้คืนข้อมูล (recovery) ข้อมูลสามารถถูกสำรองไว้เป็นประจำเพื่อป้องกันการสูญหายถาวร หากฮาร์ดแวร์เสียหรือข้อมูลถูกลบโดยไม่ได้ตั้งใจ ก็สามารถกู้คืนจากข้อมูลสำรองได้ ทำให้ระบบมีความพร้อมใช้งานสูงและธุรกิจดำเนินต่อไปได้
ความปลอดภัย (Security)#
DBMS มีฟีเจอร์ด้านความปลอดภัยเพื่อปกป้องข้อมูล มาตรการที่พบบ่อยได้แก่ การตรวจสอบตัวตน (authentication) การอนุญาต (authorization) การเข้ารหัส (encryption) และการบันทึกการเข้าถึง (auditing) ซึ่งมีความสำคัญอย่างยิ่งในระบบที่จัดเก็บข้อมูลส่วนบุคคลหรือข้อมูลการเงิน
สรุป: DBMS ช่วยให้องค์กรจัดเก็บ จัดการ รักษาความปลอดภัย และกู้คืนข้อมูลได้อย่างมีประสิทธิภาพ ทำให้ข้อมูลมีความน่าเชื่อถือ เข้าถึงได้ และปลอดภัย
2. รู้จักกับ Relational Database Management System (RDBMS)#
RDBMS (Relational Database Management System) คือ DBMS ประเภทหนึ่งที่จัดเก็บและจัดการข้อมูลโดยใช้ “ตารางที่มีความสัมพันธ์กัน” ข้อมูลถูกจัดเป็น แถว (rows) และ คอลัมน์ (columns) ทำให้สามารถจัดเก็บ ค้นหา และจัดการข้อมูลได้ง่าย ตัวอย่าง RDBMS ที่นิยมเช่นเดียวกันได้แก่ MySQL, PostgreSQL, Microsoft SQL Server และ Oracle Database
RDBMS มีส่วนประกอบและคุณสมบัติหลัก 4 อย่าง ได้แก่
ตาราง (Table)#
ส่วนประกอบพื้นฐานของ RDBMS คือตาราง ตารางประกอบด้วยแถวและคอลัมน์ โดยแต่ละแถวคือหนึ่ง record และแต่ละคอลัมน์คือหนึ่ง attribute ตัวอย่างเช่น ตาราง patient มีคอลัมน์ id, fname, lname และ gender

Key — กุญแจสำหรับระบุและเชื่อมตาราง#
Key ใช้สำหรับระบุ record ให้ไม่ซ้ำกัน และกำหนดความสัมพันธ์ระหว่างตาราง
- Primary Key (PK) — ระบุแต่ละแถวในตารางให้ไม่ซ้ำกัน
- Foreign Key (FK) — เชื่อมตารางหนึ่งไปยังอีกตารางหนึ่ง
ตัวอย่างเช่น คอลัมน์ patient.province_id อาจอ้างอิงไปยัง province.code เพื่อเชื่อมข้อมูลผู้ป่วยเข้ากับข้อมูลจังหวัด (จะอธิบายลึกในหัวข้อ Primary Key & Foreign Key)
SQL (Structured Query Language)#
SQL คือภาษาที่ใช้สื่อสารกับ RDBMS ช่วยให้เราสร้างตาราง เพิ่ม แก้ไข ลบ และดึงข้อมูลได้ SQL เป็นหนึ่งในทักษะที่สำคัญที่สุดสำหรับการทำงานกับฐานข้อมูลเชิงสัมพันธ์

จัดการความสัมพันธ์ (Relationship Management)#
คุณสมบัติสำคัญของ RDBMS คือการจัดการความสัมพันธ์ระหว่างตาราง ความสัมพันธ์รักษาไว้ผ่าน Primary Key และ Foreign Key ซึ่ง ลดข้อมูลที่ซ้ำกัน และ เพิ่มความสอดคล้องของข้อมูล ตัวอย่างเช่น ตาราง patient เชื่อมกับตาราง province ได้โดยไม่ต้องเก็บชื่อจังหวัดซ้ำในทุก record ของผู้ป่วย
สรุป: RDBMS เก็บข้อมูลในตารางที่มีความสัมพันธ์กัน โดยตาราง กุญแจ และ SQL คือส่วนประกอบหลัก RDBMS มอบการดึงข้อมูล การจัดการข้อมูล และการจัดการความสัมพันธ์ที่มีประสิทธิภาพ
3. ระบบฐานข้อมูลยอดนิยม#
ตารางด้านล่างแสดง 15 อันดับแรก ของระบบฐานข้อมูลยอดนิยม อ้างอิงจาก DB-Engines Ranking ↗ เดือนมิถุนายน 2026 คะแนน (Score) คำนวณจากปัจจัยหลายด้าน เช่น การกล่าวถึงบนเว็บ การค้นหา การมีส่วนร่วมในชุมชน และงานที่เกี่ยวข้อง — ยิ่งคะแนนสูงแปลว่ายิ่งนิยม
| อันดับ | ระบบ | ประเภท | Score (มิ.ย. 2026) |
|---|---|---|---|
| 1 | Oracle | Relational | 1140.04 |
| 2 | MySQL | Relational | 856.29 |
| 3 | Microsoft SQL Server | Relational | 698.04 |
| 4 | PostgreSQL | Relational | 688.23 |
| 5 | MongoDB | Document (NoSQL) | 387.97 |
| 6 | Snowflake | Relational | 214.57 |
| 7 | Databricks | Multi-model | 157.58 |
| 8 | Redis | Key-value (NoSQL) | 150.02 |
| 9 | IBM Db2 | Relational | 113.53 |
| 10 | Apache Cassandra | Wide column (NoSQL) | 102.97 |
| 11 | SQLite | Relational | 95.44 |
| 12 | Elasticsearch | Search engine (NoSQL) | 94.65 |
| 13 | MariaDB | Relational | 81.22 |
| 14 | Microsoft Azure SQL Database | Relational | 74.92 |
| 15 | Apache Hive | Relational | 71.54 |
สรุป: จากอันดับ DB-Engines (มิ.ย. 2026) Oracle, MySQL, Microsoft SQL Server และ PostgreSQL ครอง 4 อันดับแรกของโลก โดยส่วนใหญ่เป็น RDBMS ที่ใช้ SQL ส่วน MySQL และ PostgreSQL เป็นตัวเลือกโอเพนซอร์สยอดนิยม, Oracle / SQL Server / IBM Db2 ใช้ในองค์กรขนาดใหญ่
แหล่งอ้างอิง#
- จัดอันดับความนิยมของระบบฐานข้อมูล (อ้างอิงได้ว่าตัวไหนนิยมที่สุด): DB-Engines Ranking ↗
4. CAMPP — ชุดเครื่องมือพัฒนาเว็บบนเครื่อง#
CAMPP เป็นสภาพแวดล้อมสำหรับพัฒนาและทดสอบเว็บแอปพลิเคชันบนเครื่อง (local) ฟรีและติดตั้งง่าย โดยรวมเครื่องมือที่จำเป็น เช่น เว็บเซิร์ฟเวอร์ ระบบฐานข้อมูล และเครื่องมือจัดการฐานข้อมูล ไว้ในแพ็กเกจเดียว ทำให้นักพัฒนาสร้างสภาพแวดล้อมพัฒนาเว็บได้อย่างสมบูรณ์โดยไม่ต้องตั้งค่าแต่ละส่วนแยกกัน
ดาวน์โหลดและติดตั้ง CAMPP ได้จาก https://campp.melivecode.com/ ↗

เมื่อติดตั้งแล้ว เปิด CAMPP แล้วกด Start เพื่อเริ่มบริการต่าง ๆ

CAMPP ประกอบด้วยส่วนสำคัญดังนี้
- Caddy — เว็บเซิร์ฟเวอร์ที่รับคำขอจากเบราว์เซอร์และส่งหน้าเว็บกลับ จุดเด่นคือรองรับ HTTPS อัตโนมัติ ทำให้เว็บแอปพลิเคชันปลอดภัยขึ้น
- MySQL / MariaDB — RDBMS สำหรับจัดเก็บข้อมูลแอปพลิเคชัน เช่น บัญชีผู้ใช้ สินค้า คำสั่งซื้อ MariaDB เป็น fork จาก MySQL โดยชุมชน และรองรับ MySQL ได้สูง
- PostgreSQL — RDBMS อีกตัวที่มีฟีเจอร์ล้ำ ความเชื่อถือได้ และประสิทธิภาพสูง มักใช้กับระบบ enterprise และงาน analytics นักพัฒนาสามารถเลือก MySQL/MariaDB หรือ PostgreSQL ตามความต้องการของโปรเจค
- PHP & PHP-FPM — ภาษาฝั่งเซิร์ฟเวอร์ยอดนิยมสำหรับพัฒนาเว็บ PHP-FPM (FastCGI Process Manager) ช่วยเพิ่มประสิทธิภาพของแอปพลิเคชัน PHP ระบบดังๆ เช่น WordPress ก็สร้างด้วย PHP
- phpMyAdmin — เครื่องมือจัดการฐานข้อมูลผ่านเว็บ มี GUI สำหรับจัดการ MySQL และ MariaDB เหมาะสำหรับผู้เริ่มต้นที่ยังไม่คุ้นเคยกับ command line (อธิบายในหัวข้อถัดไป)
- Adminer — เครื่องมือจัดการฐานข้อมูลน้ำหนักเบา จุดต่างจาก phpMyAdmin คือรองรับหลายระบบฐานข้อมูลในหน้าเดียว (MySQL, MariaDB, PostgreSQL, SQLite) จึงสะดวกเมื่อต้องทำงานกับฐานข้อมูลหลายแพลตฟอร์ม
สรุป: CAMPP รวมทุกสิ่งที่จำเป็นสำหรับการพัฒนาเว็บแอปพลิเคชันบนเครื่องในแพ็กเกจเดียว ทั้งเว็บเซิร์ฟเวอร์ ฐานข้อมูล PHP และเครื่องมือจัดการฐานข้อมูล
5. phpMyAdmin — เครื่องมือจัดการฐานข้อมูลผ่านเว็บ#
phpMyAdmin เป็นเครื่องมือจัดการฐานข้อมูลผ่านเว็บ สำหรับจัดการ MySQL และ MariaDB โดยมี graphical user interface (GUI) ทำให้ผู้ใช้ทำงานกับฐานข้อมูลผ่านเว็บเบราว์เซอร์ได้ ซึ่งง่ายกว่าการใช้ command line โดยเฉพาะสำหรับผู้เริ่มต้น

phpMyAdmin ช่วยให้เราทำงานสำคัญได้หลายอย่างโดยไม่ต้องเขียน SQL เองทุกครั้ง
- สร้างฐานข้อมูลและตาราง — สร้าง database ใหม่ได้ไม่กี่คลิก และกำหนดคอลัมน์ ชนิดข้อมูล และ primary key ผ่านหน้าต่างกราฟิก
- จัดการข้อมูล — เพิ่ม แก้ไข ลบ และเรียกดู record ได้โดยตรงผ่าน interface เหมาะสำหรับทดสอบแอปพลิเคชันและตรวจสอบข้อมูลที่จัดเก็บ
- รันคำสั่ง SQL — มี SQL editor สำหรับรันคำสั่ง
SELECT,INSERT,UPDATE,DELETEได้จากเบราว์เซอร์โดยตรง ใช้ทดสอบ query และแก้ปัญหาฐานข้อมูล - นำเข้าและส่งออกข้อมูล (Import / Export) — รองรับการ import จากไฟล์ SQL, CSV และรูปแบบอื่น ๆ รวมถึง export เพื่อสำรองข้อมูล สำคัญสำหรับการย้ายข้อมูล สำรองข้อมูล และกู้คืน
- จัดการผู้ใช้และสิทธิ์ — ผู้ดูแลสามารถกำหนดสิทธิ์ระดับต่าง ๆ ให้ผู้ใช้แต่ละคน เช่น คนหนึ่งดูข้อมูลได้อย่างเดียว อีกคนสร้างและแก้ไขตารางได้ ช่วยเพิ่มความปลอดภัย
สรุป: phpMyAdmin เป็นเครื่องมือที่ทรงพลังและใช้งานง่าย ช่วยลดความซับซ้อนของการสร้างฐานข้อมูล จัดการข้อมูล รัน query สำรองข้อมูล และจัดการผู้ใช้
6. CREATE DATABASE — สร้างฐานข้อมูล#
ก่อนที่จะสร้างตารางหรือเก็บข้อมูลใด ๆ เราต้องสร้างฐานข้อมูลขึ้นมาก่อน ฐานข้อมูลทำหน้าที่เป็น “คอนเทนเนอร์” ที่รวบรวมตารางและข้อมูลที่เกี่ยวข้องกันเอาไว้ด้วยกัน
รูปแบบพื้นฐาน#
CREATE DATABASE database_name;sqlตัวอย่าง: สร้างฐานข้อมูล testdb#
-- สร้างฐานข้อมูล (ใช้ IF NOT EXISTS เพื่อไม่ให้ error หากสร้างไว้แล้ว)
CREATE DATABASE IF NOT EXISTS testdb;
-- เลือกฐานข้อมูลที่จะใช้งาน
USE testdb;sql
อธิบายแต่ละส่วน:
CREATE DATABASE— สร้างฐานข้อมูลใหม่IF NOT EXISTS— ตรวจสอบก่อนว่ายังไม่มีฐานข้อมูลชื่อนี้อยู่ ป้องกัน error เวลารันซ้ำUSE testdb— เลือกฐานข้อมูลtestdbให้เป็นฐานข้อมูลที่ใช้งาน คำสั่งCREATE TABLEและINSERTในหัวข้อถัดไปจะถูกสร้างในฐานข้อมูลนี้
เคล็ดลับ: ใน phpMyAdmin หรือ Adminer คุณสามารถสร้างและเลือกฐานข้อมูลผ่าน GUI ได้โดยไม่ต้องพิมพ์คำสั่ง SQL

7. CREATE TABLE — สร้างตาราง#
ก่อนเก็บข้อมูล เราต้องกำหนดโครงสร้างของตารางก่อน โครงสร้างนี้กำหนดว่าแต่ละคอลัมน์จะเก็บข้อมูลประเภทใด
รูปแบบพื้นฐาน#
CREATE TABLE table_name (
column1 datatype,
column2 datatype,
column3 datatype,
...
);sqlชนิดข้อมูล (Datatype) ที่ใช้บ่อย#
ตอนสร้างตาราง เราต้องระบุ ชนิดข้อมูล (datatype) ให้ทุกคอลัมน์ เพื่อบอกฐานข้อมูลว่าคอลัมน์นั้นจะเก็บข้อมูลแบบใด การเลือกชนิดข้อมูลที่เหมาะสมช่วยให้เก็บข้อมูลได้ถูกต้อง ประหยัดพื้นที่ และค้นหาได้เร็ว ชนิดข้อมูลแบ่งคร่าว ๆ เป็น 3 กลุ่มหลัก:
ตัวเลข (Numeric)
| Datatype | ใช้สำหรับ | ตัวอย่าง |
|---|---|---|
INT | จำนวนเต็ม | ID, อายุ, จำนวน |
TINYINT / SMALLINT / BIGINT | จำนวนเต็มขนาดเล็ก / กลาง / ใหญ่ | ค่า 0/1, ปีเกิด, ยอดนับขนาดใหญ่ |
DECIMAL(p,s) | ตัวเลขทศนิยมแม่นยำ | น้ำหนัก, ส่วนสูง, ราคา, เงิน |
FLOAT / DOUBLE | ตัวเลขทศนิยมลอยตัว (วิทยาศาสตร์) | พิกัด, ค่าทางวิทยาศาสตร์ |
ข้อความ (String)
| Datatype | ใช้สำหรับ | ตัวอย่าง |
|---|---|---|
VARCHAR(n) | ข้อความความยาวผันแปร (สูงสุด n ตัวอักษร) | ชื่อ, ที่อยู่, อีเมล |
CHAR(n) | ข้อความความยาวคงที่ (เสมอ n ตัวอักษร) | รหัสที่มีความยาวตายตัว เช่นรหัสประเทศ |
TEXT | ข้อความยาว | บทความ, ความคิดเห็น, คำอธิบาย |
วันที่และเวลา (Date/Time)
| Datatype | ใช้สำหรับ | ตัวอย่าง |
|---|---|---|
DATE | วันที่ (YYYY-MM-DD) | วันเกิด, วันนัดหมาย |
DATETIME / TIMESTAMP | วันที่และเวลา | เวลาที่สร้าง record, เวลาอัปเดต |
นอกจากนี้ยังมี BOOLEAN สำหรับค่าจริง/เท็จ (true/false เช่นสถานะ active) และ ENUM(...) สำหรับค่าที่เลือกจากชุดที่กำหนด เช่น gender ที่เป็น 'Male', 'Female'
เคล็ดลับ — เลือกชนิดข้อมูลอย่างไร?
- เก็บ เงินหรือราคา ใช้
DECIMALเสมอ ไม่ใช้FLOAT/DOUBLEเพราะทศนิยมลอยตัวอาจทำให้คำนวณผิดเพี้ยน- ใช้
VARCHARเป็นค่าเริ่มต้นสำหรับข้อความ ส่วนCHARเก็บเฉพาะค่าที่มีความยาวตายตัวจริง ๆ- เลือกขนาดที่ “พอดี” เช่น
TINYINTสำหรับค่า 0/1 จะประหยัดพื้นที่กว่าINT
ตัวอย่าง: สร้างตาราง 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
อธิบายโครงสร้างตาราง:
code— รหัสจังหวัด ใช้INTและเป็น Primary Key ของตารางprovincename— ชื่อจังหวัด ใช้VARCHAR(100)id— รหัสผู้ป่วย ใช้INTและเป็น Primary Key ของตารางpatient(อธิบายลึกในหัวข้อถัดไป)title— คำนำหน้าชื่อ ใช้VARCHAR(10)เช่น Mr., Ms.fname/lname— ชื่อและนามสกุล ใช้VARCHAR(100)(ข้อความไม่เกิน 100 ตัวอักษร)gender— เพศ ใช้VARCHAR(10)เช่น Male, Femaledob— วันเกิด (Date of Birth) ใช้DATEเก็บในรูปแบบYYYY-MM-DDเช่น1990-05-20province_id— รหัสจังหวัด ใช้INTเป็น Foreign Key ที่อ้างอิงไปยังprovince(code)(อธิบายในหัวข้อถัดไป)weight/height— น้ำหนักและส่วนสูง ใช้DECIMAL(5,2)รองรับทศนิยม เช่น 105.50, 175.00
หมายเหตุ: ต้องสร้างตาราง
provinceก่อนตารางpatientเพราะpatientมี Foreign Key อ้างอิงไปยังprovince(code)หากสร้างpatientก่อน ฐานข้อมูลจะ error เพราะยังไม่มีตารางprovinceให้อ้างอิง
AUTO_INCREMENT สร้าง ID ใหม่ให้อัตโนมัติเมื่อเพิ่ม record ใหม่ (1, 2, 3, …) ไม่ต้องกรอกเอง ส่วน PRIMARY KEY ระบุ record ให้ไม่ซ้ำและช่วยให้ SQL ค้นหา record ได้รวดเร็ว ตารางทุกตารางควรมี Primary Key

8. Primary Key & Foreign Key#
วิธีที่ตารางใน relational database เชื่อมต่อกันคือหัวใจของการออกแบบฐานข้อมูล การเชื่อมต่อนี้สร้างขึ้นด้วย Primary Key และ Foreign Key ทำให้เราจัดเก็บข้อมูลได้อย่างมีประสิทธิภาพโดยไม่ซ้ำซ้อน
Primary Key (PK)#
Primary Key ระบุแต่ละ record ในตารางให้ไม่ซ้ำกัน จะไม่มี record สอง record ใดที่มีค่า Primary Key เหมือนกันได้
- ในตาราง
patient→ Primary Key คือid(กำหนดด้วยid INT AUTO_INCREMENT PRIMARY KEYตอนสร้างตารางในหัวข้อที่แล้ว) - ในตาราง
province→ Primary Key คือcode
Foreign Key (FK)#
Foreign Key คือคอลัมน์ที่อ้างอิงไปยัง Primary Key ของอีกตารางหนึ่ง ในตัวอย่างนี้ patient.province_id เป็น Foreign Key ที่อ้างอิงไปยัง province.code ความสัมพันธ์นี้เชื่อมผู้ป่วยแต่ละคนเข้ากับจังหวัด

ทำความเข้าใจความสัมพันธ์#
สมมติเรามีข้อมูลในตาราง patient ดังนี้
| fname | province_id |
|---|---|
| Somchai | 10 |
| Suda | 20 |
| Anan | 10 |
เมื่อ database ไปค้น code เหล่านี้ในตาราง province จะพบว่า
- province code 10 → Bangkok
- province code 20 → Chonburi
ดังนั้น Somchai → Bangkok, Suda → Chonburi, Anan → Bangkok
ทำไมต้องใช้ Foreign Key?#
- ป้องกันข้อมูลซ้ำซ้อน — เก็บเฉพาะ code แทนชื่อจังหวัดเต็มในทุก record
- ปรับปรุงความสอดคล้องของข้อมูล — เปลี่ยนชื่อจังหวัดที่เดียวก็สะท้อนทุกที่
- ทำให้ดูแลรักษาง่ายขึ้น
- ประหยัดพื้นที่จัดเก็บ
- รับประกันว่าข้อมูลที่เกี่ยวข้องยังเชื่อมโยงกันอยู่เสมอ
สรุป: Primary Key ระบุ record ให้ไม่ซ้ำ, Foreign Key อ้างอิง Primary Key ของอีกตาราง และความสัมพันธ์นี้ลดข้อมูลซ้ำและเพิ่มความสอดคล้อง
9. ALTER TABLE — แก้ไขโครงสร้างตาราง#
หลังจากสร้างตารางไปแล้ว ความต้องการมักเปลี่ยนไปตามโปรเจค เช่น ต้องเพิ่มคอลัมน์ “เบอร์โทร” ของผู้ป่วย หรือเปลี่ยนชนิดข้อมูลของคอลัมน์ ALTER TABLE ใช้สำหรับแก้ไข โครงสร้าง ของตารางที่มีอยู่แล้ว โดยส่วนใหญ่จะไม่กระทบข้อมูลที่เก็บไว้ ซึ่งต่างจาก UPDATE (หัวข้อถัดไป) ที่ไปแก้ไข ข้อมูล ในแต่ละ record
เพิ่มคอลัมน์ (ADD COLUMN)#
-- เพิ่มคอลัมน์ phone สำหรับเก็บเบอร์โทรศัพท์ของผู้ป่วย
ALTER TABLE patient
ADD COLUMN phone VARCHAR(20);sqlคอลัมน์ใหม่ phone จะถูกเพิ่มต่อท้ายคอลัมน์เดิม ส่วนข้อมูลผู้ป่วยที่มีอยู่แล้วยังอยู่ครบทุก record เพียงแต่คอลัมน์ phone จะมีค่า NULL จนกว่าจะมีการ UPDATE ใส่เข้าไป
ลบคอลัมน์ (DROP COLUMN)#
-- ลบคอลัมน์ phone ออกจากตาราง patient
ALTER TABLE patient
DROP COLUMN phone;sql⚠️ คำเตือน: การลบคอลัมน์จะลบข้อมูลในคอลัมน์นั้นทิ้งทั้งหมดด้วย ต้องแน่ใจก่อนรัน
เปลี่ยนชนิดข้อมูล (MODIFY COLUMN)#
-- ขยายความยาวสูงสุดของ fname จาก VARCHAR(100) เป็น VARCHAR(150)
ALTER TABLE patient
MODIFY COLUMN fname VARCHAR(150);sqlหมายเหตุ: คำสั่งเปลี่ยนชนิดข้อมูลต่างกันเล็กน้อยในแต่ละระบบ — MySQL/MariaDB ใช้
MODIFY COLUMN, PostgreSQL ใช้ALTER COLUMN ... TYPE, ส่วน Microsoft SQL Server ใช้ALTER COLUMN
เปลี่ยนชื่อคอลัมน์ (RENAME COLUMN)#
-- เปลี่ยนชื่อคอลัมน์ fname เป็น first_name
ALTER TABLE patient
RENAME COLUMN fname TO first_name;sql-- เปลี่ยนชื่อคอลัมน์ first_name เป็น fname
ALTER TABLE patient
RENAME COLUMN first_name TO fname;sqlเพิ่ม Constraint เช่น Foreign Key#
ALTER TABLE ยังใช้สำหรับเพิ่ม constraint ให้ตารางที่สร้างไว้แล้ว เช่น Primary Key หรือ Foreign Key ตัวอย่างด้านล่างเพิ่ม Foreign Key ให้ province_id (หากตอนสร้างตารางยังไม่ได้กำหนด):
ALTER TABLE patient
ADD CONSTRAINT fk_province
FOREIGN KEY (province_id) REFERENCES province(code);sqlสรุป:
ALTER TABLEแก้ไขโครงสร้างตารางที่มีอยู่ เช่น เพิ่ม/ลบ/เปลี่ยน/เปลี่ยนชื่อ คอลัมน์ และเพิ่ม constraint
10. INSERT — เพิ่มข้อมูล#
INSERT ใช้สำหรับเพิ่ม record ใหม่เข้าตาราง เป็นหนึ่งในสี่คำสั่งพื้นฐานของ SQL (ร่วมกับ SELECT, UPDATE, DELETE)
รูปแบบพื้นฐาน#
INSERT INTO table_name (column1, column2, ...)
VALUES (value1, value2, ...);sqlจำนวนของ value ต้องเท่ากับจำนวนของ column และชนิดข้อมูลต้องตรงกับที่กำหนดไว้
ตัวอย่าง: เพิ่มจังหวัดหนึ่ง record#
INSERT INTO province (code, name)
VALUES (10, 'Bangkok');sqlเนื่องจากตาราง province กำหนด code เป็น Primary Key เอง (ไม่ใช่ AUTO_INCREMENT) เราจึงต้องระบุค่า code ทุกครั้ง เช่น 10 สำหรับ Bangkok
เพิ่มหลาย record ในครั้งเดียว#
-- เพิ่มข้อมูลจังหวัด
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
สังเกตว่าเราไม่ระบุ id ของตาราง patient เพราะมันเป็น AUTO_INCREMENT ฐานข้อมูลจะสร้าง ID ให้เอง (1, 2, 3, …) ส่วน province_id เราระบุเป็นรหัสจังหวัดที่ตรงกับ province.code
ข้อดีของ AUTO_INCREMENT: ป้องกัน ID ซ้ำ, สร้าง identifier ให้อัตโนมัติ, ลดข้อผิดพลาดจากมนุษย์, และทำให้การป้อนข้อมูลง่ายขึ้น
ข้อมูลตัวอย่างนี้รองรับตัวอย่าง query ในหัวข้อถัดไป เช่น:
WHERE weight > 100→ John (105), David (112), Michael (120)WHERE weight > 100 AND height < 180→ John, David, Michael (ทั้งสามคนส่วนสูง < 180)GROUP BY gender→ มีทั้งเพศ Male และ Female ให้คำนวณAVG/COUNT/SUMLEFT JOIN province→ John/David (Bangkok), Mary/Michael/Charles (Chiang Mai)
11. SELECT — ดึงข้อมูล#
หนึ่งในหน้าที่หลักของ RDBMS คือการดึงข้อมูล SELECT เป็นคำสั่งที่ใช้บ่อยที่สุด เพราะช่วยให้เราดูข้อมูลที่จัดเก็บอยู่ในตารางได้
รูปแบบพื้นฐาน#
SELECT column1, column2, ...
FROM table_name
WHERE condition;sqlทดสอบใน phpMyAdmin#
- เลือกฐานข้อมูล
testdbแล้วเลือกตารางpatientที่แผงด้านซ้าย - คลิกแท็บ SQL ด้านบนเพื่อเปิด SQL editor
- พิมพ์คำสั่ง:
SELECT * FROM patient;sql
- คลิกปุ่ม Go ที่มุมขวาล่างเพื่อรัน
อธิบายแต่ละส่วน:
SELECT— บอกว่าจะดึงข้อมูล*— หมายถึงทุกคอลัมน์FROM patient— ดึงข้อมูลจากตารางpatient
ผลลัพธ์จะแสดงทุกแถวและทุกคอลัมน์ในตาราง คือข้อมูลตัวอย่างทั้ง 12 record ที่ insert ไว้ในหัวข้อก่อนหน้า:
ผลลัพธ์:
| 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 |
เลือกเฉพาะคอลัมน์ที่ต้องการ#
-- เลือกหนึ่งคอลัมน์
SELECT fname FROM patient;
-- เลือกหลายคอลัมน์
SELECT fname, lname, dob FROM patient;
-- เลือกทุกคอลัมน์
SELECT * FROM patient;sqlSELECT fname คืนเฉพาะคอลัมน์ชื่อ:
ผลลัพธ์ (SELECT fname):
| fname |
|---|
| John |
| Mary |
| David |
| Robert |
| Linda |
| Michael |
| Sarah |
| James |
| Emily |
| Thomas |
| Jessica |
| Charles |
SELECT fname, lname, dob คืนสามคอลัมน์ (ส่วน SELECT * ให้ผลลัพธ์เหมือนตารางเต็มด้านบน):
ผลลัพธ์ (SELECT fname, lname, dob):
| 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 fname, lname, weight
FROM patient;sqlQuery นี้ดึงสามคอลัมน์คือ ชื่อ นามสกุล และน้ำหนัก จากตาราง patient และแสดงทุก record เพราะไม่มีเงื่อนไข WHERE
ผลลัพธ์:
| fname | lname | weight |
|---|---|---|
| John | Smith | 105.00 |
| Mary | Johnson | 55.00 |
| David | Lee | 112.00 |
| Robert | Brown | 80.00 |
| Linda | Wilson | 62.00 |
| Michael | Davis | 120.00 |
| Sarah | Miller | 48.00 |
| James | Taylor | 75.00 |
| Emily | Anderson | 58.00 |
| Thomas | Thomas | 95.00 |
| Jessica | Jackson | 70.00 |
| Charles | White | 88.00 |
12. WHERE — กรองข้อมูลด้วยเงื่อนไข#
WHERE ใช้สำหรับกรอง record ให้แสดงเฉพาะที่ตรงตามเงื่อนไขที่กำหนด ช่วยให้ค้นหาข้อมูลที่ต้องการจากฐานข้อมูลขนาดใหญ่ได้แม่นยำ
เงื่อนไขเดียว#
SELECT fname, lname, weight
FROM patient
WHERE weight > 100;sqlผลลัพธ์จะแสดงเฉพาะผู้ป่วยที่น้ำหนักมากกว่า 100 กิโลกรัม เช่น 105, 112, 120 kg ส่วนผู้ที่น้ำหนักน้อยกว่าหรือเท่ากับ 100 จะถูกตัดออก
ผลลัพธ์:
| fname | lname | weight |
|---|---|---|
| John | Smith | 105.00 |
| David | Lee | 112.00 |
| Michael | Davis | 120.00 |
เปรียบเทียบวันที่#
WHERE ใช้กับคอลัมน์ DATE ได้เช่นกัน โดยเปรียบเทียบกับวันที่ในรูปแบบ YYYY-MM-DD ตัวอย่างเช่น ค้นผู้ป่วยที่เกิดก่อนปี 1990:
SELECT fname, lname, dob
FROM patient
WHERE dob < '1990-01-01';sqlผลลัพธ์จะแสดงเฉพาะผู้ป่วยที่เกิดก่อนวันที่ 1990-01-01 ได้แก่ John (1985), David (1988), Michael (1983), James (1987), Charles (1982) และ Thomas (1980) ส่วนคนที่เกิดปี 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 |
หลายเงื่อนไขด้วย AND / OR#
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— ต้องเป็นจริงทั้งสองเงื่อนไข (น้ำหนัก > 100 และ ส่วนสูง < 180)OR— พอเป็นจริงอย่างน้อยหนึ่งเงื่อนไข
ตัวอย่างการใช้ AND:
SELECT *
FROM patient
WHERE gender = 'Male' AND weight > 80;
-- ต้องเป็นผู้ชาย และน้ำหนักมากกว่า 80sqlผลลัพธ์:
| 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:
SELECT *
FROM patient
WHERE gender = 'Male' OR weight > 100;
-- ผู้ชายทุกคน รวมถึงใครก็ตามที่น้ำหนักมากกว่า 100sqlผลลัพธ์ (ผู้ชายทุกคน — ไม่มีผู้หญิงคนไหนน้ำหนักเกิน 100):
| 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 |
| 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 |
| 12 | Mr. | Charles | White | Male | 1982-05-17 | 50 | 88.00 | 185.00 |
สรุป:
WHEREใช้กรอง record,ANDต้องเป็นจริงทุกเงื่อนไข,ORพอเป็นจริงเงื่อนไขเดียวก็พอ การผสมSELECTกับWHEREช่วยให้ดึงข้อมูลเฉพาะที่ต้องการได้อย่างมีประสิทธิภาพ
13. ORDER BY — เรียงลำดับผลลัพธ์#
โดยค่าเริ่มต้น record อาจแสดงในลำดับที่คาดเดาไม่ได้ ORDER BY ช่วยให้เราจัดเรียงข้อมูลตามคอลัมน์หนึ่งหรือหลายคอลัมน์ ทำให้ข้อมูลอ่านง่ายและวิเคราะห์ได้สะดวก
รูปแบบพื้นฐาน#
SELECT column1, column2, ...
FROM table_name
ORDER BY column1 ASC|DESC;sqlASC(Ascending) — น้อยไปมาก / A ไป Z (ค่าเริ่มต้นถ้าไม่ระบุ)DESC(Descending) — มากไปน้อย / Z ไป A
ตัวอย่าง: เรียงตามน้ำหนักจากมากไปน้อย#
SELECT fname, lname, weight, height
FROM patient
WHERE weight > 100 AND height < 180
ORDER BY weight DESC;sqlผลลัพธ์ (เรียงจากน้ำหนักมากไปน้อย):
| fname | lname | weight | height |
|---|---|---|---|
| Michael | Davis | 120.00 | 175.00 |
| David | Lee | 112.00 | 178.00 |
| John | Smith | 105.00 | 175.00 |
Query นี้กรองผู้ป่วยที่น้ำหนัก > 100 และส่วนสูง < 180 แล้วเรียงตามน้ำหนักจากมากไปน้อย คนที่หนักที่สุดจะอยู่บนสุด
ตัวอย่าง: เรียงตามวันเกิด (อายุ)#
SELECT fname, lname, dob
FROM patient
ORDER BY dob DESC;sqlผลลัพธ์ (วันเกิดใหม่สุด/อายุน้อยสุดอยู่บนสุด):
| 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 |
เนื่องจากค่า DATE ที่ใหญ่กว่าคือวันเกิดที่ช้ากว่า (อายุน้อยกว่า) การใช้ ORDER BY dob DESC จึงเรียงจากอายุน้อยไปมาก — คนที่อายุน้อยที่สุดอยู่บนสุด เช่น Sarah (1998), Jessica (1996) หากต้องการเรียงจากอายุมากไปน้อย ให้เปลี่ยนเป็น ORDER BY dob ASC
เรียงหลายคอลัมน์#
SELECT fname, lname, gender, weight
FROM patient
ORDER BY gender ASC, weight DESC;sqlผลลัพธ์ (เพศ 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 |
ระบบจะเรียงตามเพศก่อน (A→Z) แล้วภายในแต่ละกลุ่มเพศจะเรียงตามน้ำหนักจากมากไปน้อย การเรียงหลายคอลัมน์มีประโยชน์มากสำหรับรายงานและการวิเคราะห์ข้อมูล
สรุป:
ORDER BYใช้จัดเรียงผลลัพธ์,ASCจากน้อยไปมาก/A→Z,DESCจากมากไปน้อย/Z→A และสามารถใช้หลายคอลัมน์เพื่อการจัดเรียงขั้นสูงได้
14. GROUP BY — จัดกลุ่มและสรุปข้อมูล#
GROUP BY ใช้สำหรับจัดกลุ่มแถวที่มีค่าเดียวกันในคอลัมน์ที่กำหนด มักใช้ร่วมกับ aggregate function เช่น COUNT(), SUM(), AVG(), MIN(), MAX() แทนที่จะแสดงทุก record ตัว GROUP BY ช่วยสร้างข้อมูลสรุปได้
รูปแบบพื้นฐาน#
SELECT column1, aggregate_function(column2)
FROM table_name
GROUP BY column1;sqlตัวอย่าง: หาค่าเฉลี่ยน้ำหนักและส่วนสูงแยกตามเพศ#
SELECT gender, AVG(weight), AVG(height)
FROM patient
GROUP BY gender;sqlระบบจะแบ่ง record ออกเป็นกลุ่มตามเพศ (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
Aggregate Function อื่น ๆ#
-- นับจำนวนผู้ป่วยในแต่ละเพศ
SELECT gender, COUNT(*) FROM patient GROUP BY gender;
-- ผลรวมน้ำหนักในแต่ละเพศ
SELECT gender, SUM(weight) FROM patient GROUP BY gender;
-- น้ำหนักสูงสุดในแต่ละเพศ
SELECT gender, MAX(weight) FROM patient GROUP BY gender;
-- น้ำหนักต่ำสุดในแต่ละเพศ
SELECT gender, MIN(weight) FROM patient GROUP BY gender;sqlผลลัพธ์แต่ละ query (ทั้งสี่คำสั่งคืน 2 บรรทัด คือ Male และ Female):
COUNT(*) — จำนวนผู้ป่วย:
| gender | COUNT(*) |
|---|---|
| Male | 7 |
| Female | 5 |
SUM(weight) — ผลรวมน้ำหนัก:
| gender | SUM(weight) |
|---|---|
| Male | 675.00 |
| Female | 293.00 |
MAX(weight) — น้ำหนักสูงสุด:
| gender | MAX(weight) |
|---|---|
| Male | 120.00 |
| Female | 70.00 |
MIN(weight) — น้ำหนักต่ำสุด:
| gender | MIN(weight) |
|---|---|
| Male | 75.00 |
| Female | 48.00 |
คำนวณก่อนสรุป: หาค่าเฉลี่ย BMI แยกตามเพศ#
SQL สามารถคำนวณทางคณิตศาสตร์ภายใน query ได้ (+, -, *, /) แล้วนำผลไปใช้กับ aggregate function เช่นการหาค่าเฉลี่ย BMI
SELECT gender,
AVG(weight / ((height / 100) * (height / 100))) AS BMI
FROM patient
GROUP BY gender;sqlอธิบายการทำงาน:
- SQL คำนวณ BMI ให้ผู้ป่วยทุกคนก่อน (
weight / (เมตร²)) - แยก record ออกเป็นกลุ่มตามเพศ
AVG()คำนวณ BMI เฉลี่ยของแต่ละกลุ่มAS BMIตั้งชื่อให้คอลัมน์ผลลัพธ์ว่าBMI
ผลลัพธ์:
| gender | BMI |
|---|---|
| Male | 31.18 |
| Female | 22.37 |
ผู้ชายมี BMI เฉลี่ยสูงกว่าผู้หญิง (สอดคล้องกับน้ำหนักเฉลี่ยที่มากกว่า) ซึ่งช่วยเปรียบเทียบสมรรถภาพทางกายโดยรวมระหว่างกลุ่ม
ใช้กับวันที่: หาอายุมาก/น้อยที่สุดในแต่ละเพศ#
aggregate function เช่น MIN(), MAX() ใช้กับคอลัมน์ DATE ได้เช่นกัน เช่นหาวันเกิดเก่าที่สุด (อายุมากที่สุด) และใหม่ที่สุด (อายุน้อยที่สุด) ของผู้ป่วยในแต่ละเพศ:
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เพื่อตั้งชื่อ alias ให้คอลัมน์ผลลัพธ์ ทำให้ผลลัพธ์อ่านเข้าใจง่ายขึ้น
การประยุกต์ใช้จริง: นับผู้ป่วยตามจังหวัด, หา BMI เฉลี่ยตามเพศ, นับคำสั่งซื้อตามลูกค้า, คำนวณยอดขายรวมตามหมวดสินค้า, นับนักศึกษาตามคณะ
15. JOIN — เชื่อมหลายตารางเข้าด้วยกัน#
ใน relational database ข้อมูลมักกระจายอยู่ในหลายตารางเพื่อลดความซ้ำซ้อน เราใช้ JOIN เพื่อดูข้อมูลที่เกี่ยวข้องจากหลายตารางพร้อมกัน
LEFT JOIN#
LEFT JOIN คืน ทุก record จากตารางด้านซ้าย และ record ที่ตรงกันจากตารางด้านขวา หากไม่มี record ที่ตรงกันในตารางด้านขวา ผลลัพธ์ก็ยังแสดงข้อมูลของตารางด้านซ้าย โดยคอลัมน์ด้านขวาจะเป็น NULL
รูปแบบพื้นฐาน#
SELECT column1, column2, ...
FROM table1
LEFT JOIN table2
ON table1.column = table2.column;sqlตัวอย่าง: แสดงชื่อจังหวัดของผู้ป่วย#
SELECT patient.id,
patient.fname,
patient.dob,
patient.province_id,
province.name
FROM patient
LEFT JOIN province
ON patient.province_id = province.code;sqlผลลัพธ์:
| 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 |
อธิบายการทำงาน:
FROM patient— ตารางpatientเป็นตารางด้านซ้ายLEFT JOIN province— ตารางprovinceเป็นตารางด้านขวาON patient.province_id = province.code— กำหนดวิธีที่สองตารางเชื่อมกัน คือจับคู่ตามรหัสจังหวัด
แทนที่จะเก็บชื่อจังหวัดซ้ำในทุก record ของผู้ป่วย เราเก็บเฉพาะรหัสจังหวัด แล้วใช้ LEFT JOIN ดึงชื่อจังหวัดจากตาราง province มาแสดงเมื่อต้องการ ผลลัพธ์เช่น province code 10 → Bangkok, code 50 → Chiang Mai หากรหัสจังหวัดไม่มีอยู่ในตาราง province ข้อมูลผู้ป่วยจะยังแสดง แต่ชื่อจังหวัดจะเป็น NULL
ใช้ Table Alias เพื่อให้ query สั้นและอ่านง่ายขึ้น#
การเขียนชื่อตารางเต็ม ๆ ซ้ำ ๆ ทำให้ query ยาวและอ่านยาก เราสามารถใช้ 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;sqlผลลัพธ์: เหมือนเดิมกับ query ด้านบน (12 แถวเดียวกัน) — alias เป็นเพียงชื่อย่อที่ทำให้เขียนสั้นลง ไม่เปลี่ยนแปลงผลลัพธ์
patientมี alias เป็นpprovinceมี alias เป็นpr
แทนที่จะเขียน patient.id ก็เขียน p.id แทน Query สั้นลงแต่ให้ผลลัพธ์เหมือนเดิม การใช้ alias ถือเป็น best practice โดยเฉพาะเมื่อ join หลายตาราง เช่น student s, course c, enrollment e
สรุป:
LEFT JOINรวมข้อมูลจากสองตารางโดยคืนทุก record ของตารางด้านซ้ายเสมอ หากไม่มีข้อมูลตรงกัน คอลัมน์ด้านขวาจะเป็นNULLและการใช้ table alias ช่วยให้ query สะอาดและอ่านง่ายขึ้น
16. UPDATE — แก้ไขข้อมูล#
UPDATE ใช้สำหรับแก้ไข record ที่มีอยู่แล้ว ต่างจาก INSERT ที่เพิ่ม record ใหม่
รูปแบบพื้นฐาน#
UPDATE table_name
SET column1 = value1,
column2 = value2
WHERE condition;sqlตัวอย่าง: แก้ไขน้ำหนักผู้ป่วย id = 1#
UPDATE patient
SET weight = 75
WHERE id = 1;sqlระบบจะค้นหา record ที่ id = 1 แล้วอัปเดตคอลัมน์ weight เป็น 75 ส่วน record อื่นยังคงเหมือนเดิม
แก้ไขหลายคอลัมน์พร้อมกัน#
UPDATE patient
SET weight = 75,
height = 180
WHERE id = 1;sql⚠️ คำเตือนสำคัญ: หากละเว้น
WHERErecord ทุก record ในตารางจะถูกอัปเดต!sqlUPDATE patient SET weight = 75; -- ทุกคนจะมีน้ำหนัก 75กรณีส่วนใหญ่ไม่ใช่สิ่งที่ตั้งใจ ให้ตรวจสอบเงื่อนไข
WHEREเสมอก่อนรันUPDATE
สรุป:
UPDATEแก้ไขข้อมูลที่มีอยู่,SETกำหนดค่าใหม่,WHEREควบคุมว่าจะกระทบ record ใด การใช้WHEREให้ถูกต้องมีความสำคัญมากเพื่อป้องกันการอัปเดตโดยไม่ได้ตั้งใจ
17. DELETE — ลบข้อมูล#
DELETE ใช้สำหรับลบ record ออกจากตารางอย่างถาวร ต่างจาก UPDATE ที่แก้ไขข้อมูล เนื่องจากสามารถลบข้อมูลสำคัญได้ จึงต้องใช้อย่างระมัดระวัง
รูปแบบพื้นฐาน#
DELETE FROM table_name
WHERE condition;sqlตัวอย่าง: ลบผู้ป่วย id = 1#
DELETE FROM patient
WHERE id = 1;sqlระบบจะค้นหา record ที่ id = 1 แล้วลบทิ้ง ส่วน record อื่นไม่ได้รับผลกระทบ
ลบหลาย record#
DELETE FROM patient
WHERE weight > 100;sqlQuery นี้ลบผู้ป่วยทุกคนที่น้ำหนักมากกว่า 100 อาจมีมากกว่าหนึ่ง record ถูกลบขึ้นกับข้อมูล
⚠️ คำเตือนสำคัญ: หากละเว้น
WHERErecord ทุก record ในตารางจะถูกลบ!sqlDELETE FROM patient; -- ลบข้อมูลทุก record โครงสร้างตารางยังอยู่ แต่ข้อมูลหายหมดให้ตรวจสอบ query เสมอก่อนรัน
DELETE
สรุป:
DELETEลบข้อมูลออกจากตาราง,DELETE FROMระบุตารางเป้าหมาย,WHEREระบุ record ที่จะลบ การใช้WHEREอย่างระมัดระวังจำเป็นมากเพื่อป้องกันการสูญเสียข้อมูลโดยไม่ได้ตั้งใจ
18. ตัวอย่าง Prompt สำหรับสร้าง SQL ด้วย Generative AI#
เราสามารถใช้ ChatGPT หรือ Claude ช่วยสร้าง SQL ได้ โดยให้บริบทที่ชัดเจน ตัวอย่างเช่น
Prompt 1 — สรุปข้อมูลด้วย GROUP BY:
นี่คือข้อมูลในตาราง
patient:SELECT id, title, fname, lname, gender, province, weight, height FROM patient WHERE 1จงสร้าง SQL สำหรับหาค่าเฉลี่ยน้ำหนักและส่วนสูงของแต่ละเพศ
Prompt 2 — สร้างตารางและ dummy data:
Generate an SQL script that creates a doctor table with the columns doctor_id (AUTO_INCREMENT PRIMARY KEY), first_name, last_name, specialty, and phone, using appropriate SQL data types, and then generate SQL INSERT statements to populate the table with 10 realistic sample doctor records.
เคล็ดลับ: ยิ่งบอกโครงสร้างตารางและสิ่งที่ต้องการให้ชัดเท่าไหร่ SQL ที่ได้ก็ยิ่งตรงความต้องการมากขึ้นเท่านั้น
19. สรุป#
บทความนี้ครอบคลุมพื้นฐาน Relational Database ตั้งแต่แนวคิดไปจนถึงการปฏิบัติ:
- DBMS — ซอฟต์แวร์สำหรับสร้าง จัดการ รักษาความปลอดภัย และกู้คืนข้อมูล
- RDBMS — เก็บข้อมูลในตารางที่มีความสัมพันธ์กัน พร้อมตัวอย่างระบบยอดนิยม (MySQL, PostgreSQL, Oracle, ฯลฯ)
- CAMPP & phpMyAdmin — เครื่องมือสำหรับสร้างสภาพแวดล้อมพัฒนาและจัดการฐานข้อมูลบนเครื่อง
- Table, Primary Key, Foreign Key — ส่วนประกอบหลักและความสัมพันธ์ระหว่างตาราง
- SQL ครบทุกคำสั่ง —
CREATE DATABASE,CREATE TABLE,ALTER TABLE,INSERT,SELECT,WHERE,ORDER BY,GROUP BY,JOIN,UPDATE,DELETE
เมื่อเข้าใจพื้นฐานเหล่านี้แล้ว คุณจะสามารถออกแบบตาราง จัดการข้อมูล และดึงข้อมูลเชิงสัมพันธ์ได้อย่างมั่นใจ พร้อมต่อยอดสู่การทำ report, analytics และการพัฒนาแอปพลิเคชันที่เชื่อมต่อฐานข้อมูล