Bài tập SQL

Bài tập SQL từ cơ bản đến nâng cao

BÀI SQL Cơ bản – CHỦ ĐỀ: HỆ THỐNG BÁN HÀNG / ĐƠN HÀNG

 Bảng users

users (

    id BIGINT PRIMARY KEY,

    username VARCHAR(50),

    full_name VARCHAR(100),

    email VARCHAR(100),

    department_id BIGINT,

    status INT,          -- 1: active, 0: inactive

    created_at TIMESTAMP

)


 Bảng departments

departments (

    id BIGINT PRIMARY KEY,

    name VARCHAR(100)

)


 Bảng documents

documents (

    id BIGINT PRIMARY KEY,

    title VARCHAR(255),

    creator_id BIGINT,

    status VARCHAR(20),   -- draft, processing, completed

    created_at TIMESTAMP

)


 Bảng document_logs

document_logs (

    id BIGINT PRIMARY KEY,

    document_id BIGINT,

    action VARCHAR(50),   -- create, approve, reject, view

    user_id BIGINT,

    created_at TIMESTAMP

)


 


 

Bài test

⏱ Thời gian gợi ý: 30–40 phút
🎯 Mục tiêu:

 


 

 Câu 1: Lấy danh sách user đang hoạt động

Yêu cầu:
Lấy username, full_name, email của user có status = 1

 


 

 Câu 2: User theo phòng ban

Yêu cầu:
Lấy danh sách user kèm tên phòng ban, sắp xếp theo tên phòng ban tăng dần

 


 

 Câu 3: Đếm số user theo phòng ban

Yêu cầu:
Mỗi phòng ban có bao nhiêu user (chỉ tính user active)

Output:

department_name | total_users

 


 

 Câu 4: Văn bản do user tạo

Yêu cầu:
Lấy danh sách văn bản (title, created_at) do user có username = 'admin' tạo


 


 

 Câu 5: Thống kê văn bản theo trạng thái

Yêu cầu:
Đếm số văn bản theo từng status



 


 

Tiêu chí pass Cơ bản





BÀI TEST SQL – CHỦ ĐỀ: HỆ THỐNG BÁN HÀNG / ĐƠN HÀNG

 


 

I. MÔ TẢ CHUNG

Giả định CSDL: MySQL / PostgreSQL

 


 

1️⃣ Bảng customers

customers (

    id BIGINT PRIMARY KEY,

    customer_code VARCHAR(50),

    full_name VARCHAR(100),

    email VARCHAR(100),

    status INT,           -- 1: active, 0: inactive

    created_at TIMESTAMP

)


 


 

2️⃣ Bảng products

products (

    id BIGINT PRIMARY KEY,

    product_code VARCHAR(50),

    name VARCHAR(255),

    price DECIMAL(12,2),

    status INT            -- 1: selling, 0: stopped

)


 


 

3️⃣ Bảng orders

orders (

    id BIGINT PRIMARY KEY,

    order_code VARCHAR(50),

    customer_id BIGINT,

    order_date TIMESTAMP,

    status VARCHAR(20)    -- new, paid, cancelled, completed

)


 


 

4️⃣ Bảng order_items

order_items (

    id BIGINT PRIMARY KEY,

    order_id BIGINT,

    product_id BIGINT,

    quantity INT,

    unit_price DECIMAL(12,2)

)


 


 

5️⃣ Bảng payment_logs

payment_logs (

    id BIGINT PRIMARY KEY,

    order_id BIGINT,

    payment_method VARCHAR(50),  -- cash, bank, momo

    amount DECIMAL(12,2),

    payment_time TIMESTAMP

)


 


 

II. BÀI TEST SQL – MỨC ĐỘ CƠ BẢN

⏱ Thời gian: 30–40 phút
🎯 Mục tiêu:

 


 

🟢 Câu 1: Khách hàng đang hoạt động

Yêu cầu:
Lấy danh sách customer_code, full_name, email của khách hàng có status = 1

 


 

🟢 Câu 2: Danh sách đơn hàng kèm tên khách hàng

Yêu cầu:
Lấy order_code, order_date, status, full_name

Sắp xếp theo order_date giảm dần

 


 

🟢 Câu 3: Thống kê số đơn theo trạng thái

Yêu cầu:
Đếm số lượng đơn theo từng status

 


 

🟢 Câu 4: Sản phẩm trong một đơn hàng

Yêu cầu:
Với order_code = 'ORD001', liệt kê:

product_code | product_name | quantity | unit_price


 


 

🟢 Câu 5: Tổng tiền của mỗi đơn hàng

Yêu cầu:
Tính tổng tiền = SUM(quantity * unit_price) cho từng đơn hàng

 


 

✅ Tiêu chí pass Cơ bản

 


 

III. BÀI TEST SQL – MỨC ĐỘ NÂNG CAO

⏱ Thời gian: 60–90 phút
🎯 Mục tiêu:

 


 

🔵 Câu 1: Khách hàng chưa từng đặt đơn

Yêu cầu:
Liệt kê khách hàng chưa có bất kỳ order nào

 


 

🔵 Câu 2: Đơn hàng chưa được thanh toán

Yêu cầu:
Lấy danh sách đơn hàng không có bản ghi trong payment_logs

 


 

🔵 Câu 3: Đơn hàng có tổng tiền khác tổng thanh toán

Yêu cầu:
Phát hiện các đơn hàng mà:

SUM(order_items) ≠ SUM(payment_logs.amount)


➡️ Mục tiêu: kiểm thử sai lệch dữ liệu tài chính

 


 

🔵 Câu 4: Sản phẩm bán chạy nhất

Yêu cầu:
Tìm sản phẩm có tổng số lượng bán ra cao nhất
(Chỉ tính đơn status = 'completed')

 


 

🔵 Câu 5: Lần mua gần nhất của mỗi khách hàng

Yêu cầu:
Với mỗi khách hàng, lấy đơn hàng mới nhất

Output:

customer_code | full_name | last_order_date


➡️ Gợi ý:

 


 

🔵 Câu 6: Phát hiện dữ liệu bất thường

Yêu cầu:
Liệt kê:

  1. order_items có product_id không tồn tại

  2. orders có customer_id không tồn tại

➡️ Mục tiêu: Data Integrity Testing

 


 

🔵 Câu 7 (Bonus – Tư duy hệ thống)

Câu hỏi lý thuyết:

  1. Nên index những cột nào?

  2. Vì sao không nên tính tổng tiền từ orders.total_amount nếu có order_items?

 


 



ĐỀ TEST SQL – CHỦ ĐỀ: QUẢN LÝ SINH VIÊN

⏱ Thời gian làm bài: 90 phút
 🎯 Mục tiêu đánh giá:

     Viết SQL chính xác

     Hiểu nghiệp vụ giáo dục

     Phát hiện dữ liệu bất thường

     Tư duy kiểm thử dữ liệu


I. MÔ TẢ HỆ THỐNG & CSDL

Giả định DB: MySQL / PostgreSQL


1️⃣ Bảng students

students (

    id BIGINT PRIMARY KEY,

    student_code VARCHAR(20),

    full_name VARCHAR(100),

    gender VARCHAR(10),       -- male, female

    date_of_birth DATE,

    class_id BIGINT,

    status VARCHAR(20),       -- studying, graduated, dropped

    created_at TIMESTAMP

)

 


2️⃣ Bảng classes

classes (

    id BIGINT PRIMARY KEY,

    class_code VARCHAR(20),

    class_name VARCHAR(100),

    department VARCHAR(100)

)

 


3️⃣ Bảng subjects

subjects (

    id BIGINT PRIMARY KEY,

    subject_code VARCHAR(20),

    subject_name VARCHAR(100),

    credit INT

)

 


4️⃣ Bảng enrollments

enrollments (

    id BIGINT PRIMARY KEY,

    student_id BIGINT,

    subject_id BIGINT,

    semester VARCHAR(20),     -- 2024-1, 2024-2

    score DECIMAL(4,2)

)

 


5️⃣ Bảng attendance_logs

attendance_logs (

    id BIGINT PRIMARY KEY,

    student_id BIGINT,

    subject_id BIGINT,

    attend_date DATE,

    status VARCHAR(20)        -- present, absent

)

 


II. PHẦN A – SQL CƠ BẢN

⏱ Thời gian gợi ý: 35–40 phút


🟢 Câu 1: Danh sách sinh viên đang học

Yêu cầu:
 Lấy student_code, full_name, gender, status của sinh viên có status = 'studying'


🟢 Câu 2: Sinh viên và lớp học

Yêu cầu:
 Lấy danh sách sinh viên kèm class_code, class_name


🟢 Câu 3: Số sinh viên theo khoa

Yêu cầu:
 Thống kê số lượng sinh viên theo department


🟢 Câu 4: Môn học mà sinh viên đăng ký

Yêu cầu:
 Với student_code = 'SV001', liệt kê:

subject_code | subject_name | semester | score

 


🟢 Câu 5: Điểm trung bình của mỗi sinh viên

Yêu cầu:
 Tính điểm trung bình (AVG) của từng sinh viên


✅ Tiêu chí pass Cơ bản

     JOIN đúng

     GROUP BY chính xác

     Không SELECT *

     SQL chạy được


III. PHẦN B – SQL NÂNG CAO

⏱ Thời gian gợi ý: 50–55 phút


🔵 Câu 6: Sinh viên chưa đăng ký môn học nào

Yêu cầu:
 Liệt kê sinh viên không có bản ghi trong enrollments


🔵 Câu 7: Sinh viên trượt môn

Yêu cầu:
 Liệt kê sinh viên có bất kỳ môn nào có score < 5


🔵 Câu 8: Môn học có số sinh viên đăng ký nhiều nhất

Yêu cầu:
 Tìm môn học có số lượng sinh viên đăng ký cao nhất


🔵 Câu 9: Lần điểm danh gần nhất của mỗi sinh viên

Yêu cầu:
 Với mỗi sinh viên, lấy bản ghi điểm danh mới nhất (ngày & trạng thái)


🔵 Câu 10: Phát hiện dữ liệu bất thường

Yêu cầu:
 Liệt kê:

  1. enrollmentsstudent_id không tồn tại

  2. attendance_logssubject_id không tồn tại

➡️ Mục tiêu: Data Integrity Testing


🔵 Câu 11 (Bonus – Tư duy hệ thống)

Câu hỏi ngắn:

  1. Nên index những cột nào?

  2. Vì sao không nên lưu điểm trung bình sẵn trong bảng students?

 

ĐỀ TEST SQL – CHỦ ĐỀ: QUẢN LÝ Y TẾ

Thời gian làm bài: 90 phút

🎯 Mục tiêu đánh giá:
- Viết SQL chính xác
- Hiểu nghiệp vụ y tế
- Phát hiện dữ liệu bất thường
- Tư duy kiểm thử dữ liệu


I. MÔ TẢ HỆ THỐNG & CSDL

Giả định DB: MySQL / PostgreSQL

1️⃣ Bảng patients
patients (
                id BIGINT PRIMARY KEY,
                patient_code VARCHAR(20),
                full_name VARCHAR(100),
                gender VARCHAR(10),
                date_of_birth DATE,
                phone VARCHAR(20),
                status VARCHAR(20),
                created_at TIMESTAMP
)


2️⃣ Bảng doctors
doctors (
                id BIGINT PRIMARY KEY,
                doctor_code VARCHAR(20),
                full_name VARCHAR(100),
                specialty VARCHAR(100),
                department VARCHAR(100),
                status VARCHAR(20)
)


3️⃣ Bảng appointments
appointments (
                id BIGINT PRIMARY KEY,
                patient_id BIGINT,
                doctor_id BIGINT,
                appointment_date DATE,
                appointment_time TIME,
                status VARCHAR(20)
)


4️⃣ Bảng medical_records
medical_records (
                id BIGINT PRIMARY KEY,
                patient_id BIGINT,
                doctor_id BIGINT,
                diagnosis TEXT,
                visit_date DATE,
                note TEXT
)


5️⃣ Bảng prescriptions
prescriptions (
                id BIGINT PRIMARY KEY,
                medical_record_id BIGINT,
                medicine_name VARCHAR(100),
                dosage VARCHAR(50),
                days INT
)


II. PHẦN A – SQL CƠ BẢN

⏱ Thời gian gợi ý: 35–40 phút

Câu 1: Danh sách bệnh nhân đang hoạt động
Lấy patient_code, full_name, gender, status của bệnh nhân có status = 'active'.

Câu 2: Lịch hẹn khám và bác sĩ
Liệt kê patient_code, patient_name, doctor_name, specialty, appointment_date, status.

Câu 3: Số lượng bác sĩ theo khoa
Thống kê số lượng bác sĩ theo department.

Câu 4: Lịch sử khám của bệnh nhân
Với patient_code = 'BN001', liệt kê visit_date, doctor_name, diagnosis.

Câu 5: Số lượt khám của mỗi bệnh nhân
Đếm số bản ghi medical_records của từng bệnh nhân.

III. PHẦN B – SQL NÂNG CAO

⏱ Thời gian gợi ý: 50–55 phút

Câu 6: Bệnh nhân chưa từng đi khám
Liệt kê bệnh nhân không có bản ghi trong medical_records.

Câu 7: Bác sĩ có lịch hẹn bị hủy
Liệt kê bác sĩ có ít nhất 1 lịch hẹn status = 'canceled'.

Câu 8: Bác sĩ khám nhiều bệnh nhân nhất
Tìm bác sĩ có số lượt khám nhiều nhất.

Câu 9: Lần khám gần nhất của mỗi bệnh nhân
Lấy patient_code, last_visit_date, doctor_name, diagnosis.

Câu 10: Phát hiện dữ liệu bất thường
Liệt kê appointments có patient_id không tồn tại và prescriptions có medical_record_id không tồn tại.

Câu 11 (Bonus): Tư duy hệ thống
1. Nên index những cột nào?
2. Vì sao không nên lưu tổng số lượt khám trong bảng patients?