Câu 1Trong những đáp án sau, đâu là kết quả đúng của SELECT 10 % 3;?
Hàm ① — Số học, Nối chuỗi và Hàm ngày tháng
Bài đầu trong ba bài về hàm SQL. Bao gồm các toán tử số học + - * / %, nối chuỗi với || và CONCAT, và các hàm ngày tháng như thời gian hiện tại và trích xuất năm / tháng — tất cả trên tập dữ liệu staff được tải từ CSV.
Dữ liệu dùng trong bài này — bảng staff
Bắt đầu từ bài này, ba bài tiếp theo bao gồm các hàm được tích hợp sẵn trong SQL. Bài đầu tiên tập trung vào ba nhóm: phép toán số học, nối chuỗi, và hàm ngày tháng — tất cả đều là biểu thức bạn thường đặt vào danh sách cột của SELECT.
Tập dữ liệu là bảng staff (10 hàng: id / name / birthday / city / salary), được tự động tải từ CSV. Qua bốn bài thực hành, bạn sẽ làm phép tính tiền với salary, xây dựng nhãn từ name và city, và định dạng ngày từ birthday.
Toán tử số học — +, -, *, /, %
Đối với phép tính trên cột số, bạn có 5 toán tử số học + - * / %. SQL cho phép bạn viết biểu thức trực tiếp trong danh sách cột của SELECT, nên bạn có thể lấy giá trị từ bảng và trả về kết quả đã tính dưới dạng cột riêng. Thêm AS bí_danh đặt tên cho cột kết quả, giúp dễ hiển thị hoặc xử lý ở mã downstream.
Phép chia / hoạt động khác nhau giữa các CSDL: trong phép chia giữa hai số nguyên, một số CSDL (PostgreSQL / SQL Server) trả về kết quả nguyên, trong khi các CSDL khác (MySQL / console của khóa học này = SQLite) tự động trả về số thập phân.
-- 1) Phép tính đơn giản không cần bảng
SELECT 1 + 1; -- 2
SELECT 10 - 3; -- 7
SELECT 3 * 4; -- 12
SELECT 10.0 / 3; -- 3.333...
SELECT 10 % 3; -- 1
-- 2) Phép tính dùng cột (lương năm sau khi tăng 10%)
SELECT name, salary, salary * 1.1 AS next_year_salary
FROM staff;
-- 3) Tính lương tháng (năm / 12)
SELECT name, salary / 12 AS monthly_salary FROM staff;
+ - * / % có cùng ý nghĩa như trong hầu hết các ngôn ngữ lập trình.Nối chuỗi — `||` và `CONCAT()`
Việc nối nhiều chuỗi thành một được gọi là nối chuỗi (concatenation). Có hai cách viết: console của khóa học này (SQLite), PostgreSQL, Oracle và SQL Server dùng toán tử `||` (hai gạch đứng), trong khi MySQL dùng hàm `CONCAT()`. SQLite thực ra hỗ trợ cả hai || và CONCAT(), nên bài này tập trung vào hàm CONCAT() có tính di động cao hơn.
Bằng cách chèn dấu phân cách (': ' hoặc ' / ') giữa các giá trị, bạn có thể gộp name và city thành một cột dễ đọc như «Alice Tanaka / Tokyo». Đây là công cụ chủ lực cho báo cáo và xuất CSV khi bạn muốn «gộp nhiều cột thành một».
-- 1) Toán tử || (SQLite / PostgreSQL / Oracle)
SELECT name || ' (' || city || ')' AS label FROM staff;
-- 2) Hàm CONCAT (MySQL / SQLite 3.40+ / PostgreSQL)
SELECT CONCAT(name, ' (', city, ')') AS label FROM staff;
-- Cả hai trả về cùng kết quả
-- → Alice Tanaka (Tokyo) / Bob Suzuki (Osaka) / ...
`||` vs. `CONCAT()` — chọn cái nào
Vì tính di động, `CONCAT()` là lựa chọn an toàn hơn. Nó chạy trên SQLite, MySQL, PostgreSQL, SQL Server (2012+) và Oracle. || là chuẩn SQL, nhưng trong MySQL nó mặc định là OR logic, nên nếu môi trường production có thể là MySQL, chọn CONCAT() nghĩa là bạn không cần viết lại gì.
Xử lý NULL cũng khác nhau: NULL || 'A' trả về NULL với toán tử ||. CONCAT(NULL, 'A') trả về chuỗi rỗng trong MySQL nhưng NULL trong PostgreSQL — hành vi khác nhau. Khi NULL có thể lẻn vào dữ liệu đầu vào, bao chúng bằng COALESCE(cột, '') để chuyển NULL thành chuỗi rỗng trước khi nối (COALESCE được đề cập trong bài thứ ba của loạt bài này).
Hàm ngày tháng — thời gian hiện tại và định dạng
Đối với những việc như «đóng dấu thời gian hiện tại lên bản ghi mới» hoặc «trích xuất chỉ năm từ sinh nhật», bạn dùng hàm ngày tháng. Hàm ngày tháng là một trong những nhóm mà tên hàm và cú pháp khác nhau nhiều nhất giữa các CSDL — console của khóa học này (SQLite) và MySQL gọi chúng khá khác nhau.
Khóa học này dùng datetime('now') / date('now') / strftime('format', giá_trị) của SQLite cho các bài thực hành, với NOW() / CURDATE() / DATE_FORMAT(giá_trị, 'format') của MySQL được hiển thị song song trong bảng so sánh bên dưới. Các chuỗi định dạng ('%Y' cho năm, '%m' cho tháng, '%d' cho ngày, v.v.) giống nhau trong cả hai CSDL, nên ít nhất các định danh định dạng chuyển trực tiếp.
-- Cách viết trong console của khóa học này (SQLite)
-- 1) Thời gian hiện tại / ngày hiện tại
SELECT datetime('now') AS current_dt, date('now') AS current_d;
-- 2) Định danh định dạng (chỉ năm / năm-tháng)
SELECT strftime('%Y', '1990-04-15') AS year_only; -- '1990'
SELECT strftime('%Y-%m', '1990-04-15') AS year_month; -- '1990-04'
-- 3) Định dạng áp dụng cho cột
SELECT name, strftime('%Y', birthday) AS birth_year FROM staff;
-- Tham khảo: tương tự trong MySQL
-- SELECT NOW(), CURDATE();
-- SELECT DATE_FORMAT(birthday, '%Y') FROM staff;
| Mục đích | Console khóa học này (SQLite) | MySQL |
|---|---|---|
| Thời gian hiện tại | datetime('now') | NOW() |
| Ngày hiện tại | date('now') | CURDATE() |
| Trích xuất năm | strftime('%Y', d) | DATE_FORMAT(d, '%Y') |
| Định dạng tùy chỉnh | strftime('%Y-%m-%d', d) | DATE_FORMAT(d, '%Y-%m-%d') |
Kiểm tra kiến thức
Hãy trả lời từng câu hỏi một.
Câu 2Trong console của khóa học này, đâu là cách đúng để gộp name và city thành một cột như Alice Tanaka (Tokyo)?
Câu 3Trong console của khóa học này (SQLite), đâu là cách đúng để trích xuất chỉ năm 4 chữ số từ cột birthday?