Trong bài này
Cô Mai chuẩn bị danh sách để chia nhóm học viên. Cô cần tên và khối lớp, còn người phụ trách quà cần tên và số xu. Cả hai cùng đọc một bảng học viên nhưng cần những cột khác nhau. Bạn có thể tạo hai bảng kết quả riêng mà vẫn giữ nguyên hồ sơ ban đầu.
Chọn cột theo câu hỏi của người đọc
Trước khi viết, hãy nói rõ người nhận cần thông tin gì. Danh sách chia nhóm cần tên và khối, nên bạn chọn name và grade. Mã, thành phố và số xu vẫn được lưu nhưng chưa cần đưa vào báo cáo.
Truy vấn (query) là yêu cầu lấy thông tin từ cơ sở dữ liệu. Trong câu đọc đơn giản, SELECT nêu các cột cần lấy, còn FROM nêu bảng nguồn. Một mệnh đề (clause) là một phần của câu lệnh đảm nhiệm một việc như chọn cột hoặc chỉ nguồn.
Bạn lấy hai cột phục vụ việc chia nhóm bằng câu sau:
Dữ liệu đầu vào
students6 dòng · chọn 2 cột| id | name | grade |
|---|---|---|
| 1 | An | 6 |
| 2 | Bình | 7 |
| 3 | Chi | 8 |
| 4 | Dung | 6 |
| 5 | Huy | 9 |
| 6 | Lan | 7 |
Câu lệnh
SELECT name, grade
FROM students;Kết quả
| name | grade |
|---|---|
| An | 6 |
| Bình | 7 |
| Chi | 8 |
| Dung | 6 |
| Huy | 9 |
| Lan | 7 |
Kết quả có cột name đứng trước grade. Mỗi học viên góp một dòng vì câu lệnh chưa yêu cầu lọc dòng. Hai bạn cùng khối vẫn có hai dòng riêng, chứ không tự gộp thành một khối.
Bạn đọc câu lệnh thành lời: lấy tên và khối từ bảng học viên. Dấu phẩy ngăn cách các cột. Dấu chấm phẩy kết thúc câu lệnh. Cách xuống dòng giúp nhìn ra hai phần, nhưng xuống dòng không thay cho dấu phẩy.
| Phần câu lệnh | Câu hỏi nó trả lời |
|---|---|
SELECT name, grade | Cần những thông tin nào, theo thứ tự nào? |
FROM students | Các thông tin đó nằm trong bảng nào? |
Nếu bản in cần khối trước tên, bạn đổi thứ tự danh sách cột. Đây là thay đổi cách trình bày, không phải đổi vị trí cột được lưu. Hãy chạy để đối chiếu tiêu đề hai bảng kết quả:
Dữ liệu đầu vào
students6 dòng| name | grade |
|---|---|
| An | 6 |
| Bình | 7 |
| Chi | 8 |
| Dung | 6 |
| Huy | 9 |
| Lan | 7 |
Câu lệnh
SELECT grade, name
FROM students;Kết quả
| grade | name |
|---|---|
| 6 | An |
| 7 | Bình |
| 8 | Chi |
| 6 | Dung |
| 9 | Huy |
| 7 | Lan |
Bạn vẫn thấy đủ học viên, nhưng người đọc gặp khối trước rồi mới tới tên. Trong bài thực hành, thứ tự cột thuộc yêu cầu cần đáp ứng. Một kết quả đủ thông tin vẫn có thể sai nếu đảo hai cột.
Không có yêu cầu sắp xếp trong các ví dụ này. Vì thế, hãy đối chiếu dữ liệu theo tên hoặc mã, thay vì nhớ ai đứng ở dòng đầu. Bài 5 sẽ dạy cách yêu cầu một thứ tự dòng cụ thể.
Đặt tên rõ nghĩa cho cột báo cáo
Người nhận có thể muốn tiêu đề student_name thay cho name. Bạn đặt bí danh (alias), tức tên dùng cho cột trong kết quả của một truy vấn. Từ khóa AS nối biểu thức cần đọc với tên muốn hiển thị.
Để tên học viên có tiêu đề mới, bạn viết:
Dữ liệu đầu vào
students6 dòng| id | name |
|---|---|
| 1 | An |
| 2 | Bình |
| 3 | Chi |
| 4 | Dung |
| 5 | Huy |
| 6 | Lan |
Câu lệnh
SELECT id, name AS student_name
FROM students;Kết quả
| id | student_name |
|---|---|
| 1 | An |
| 2 | Bình |
| 3 | Chi |
| 4 | Dung |
| 5 | Huy |
| 6 | Lan |
Cột thứ hai mang tên student_name, còn các ô vẫn chứa An, Bình và những tên đã lưu. AS không thay nội dung của các ô. Nó cũng không đổi cấu trúc bảng students.
Khi đọc name AS student_name, hãy đọc phần bên trái trước: lấy giá trị từ name. Phần bên phải chỉ đặt tiêu đề cho giá trị đó. Nếu chỉ viết student_name, máy sẽ đi tìm một cột nguồn có tên như vậy.
Bạn kiểm tra cách viết sai này để nhận ra nguyên nhân:
Dữ liệu đầu vào
students6 dòng| id | name |
|---|---|
| 1 | An |
| 2 | Bình |
| 3 | Chi |
| 4 | Dung |
| 5 | Huy |
| 6 | Lan |
Câu lệnh
SELECT student_name
FROM students;Thông báo lỗi
student_name
SQLite báo không tìm thấy cột. Để sửa, bạn đọc name rồi đặt lại bí danh nếu cần. Các ví dụ là những lần đọc riêng. Tiêu đề của lần đọc trước không trở thành cột mới trong nguồn.
| Bạn muốn làm gì? | Cách dùng trong truy vấn đọc |
|---|---|
| Đọc tên đã lưu | Chọn name |
| Đổi tiêu đề tên trong báo cáo | Chọn name AS student_name |
| Đọc mã rồi đến tên có tiêu đề mới | Chọn id, name AS student_name |
Một tên báo cáo nên diễn tả đúng ý nghĩa, chẳng hạn current_coins cho số xu hiện tại. Đặt bí danh bằng chữ không dấu, nối các từ bằng dấu gạch dưới (current_coins). Tên có dấu cách phải đặt trong nháy kép, dễ gõ sai.
Quên dấu phẩy có thể không báo lỗi
Nếu thiếu dấu phẩy giữa hai cột, bạn có thể nhận được một kết quả gây nhầm lẫn. Hãy xem câu lệnh sau:
Dữ liệu đầu vào
students6 dòng| name | grade |
|---|---|
| An | 6 |
| Bình | 7 |
| Chi | 8 |
| Dung | 6 |
| Huy | 9 |
| Lan | 7 |
Câu lệnh
SELECT name grade
FROM students;Kết quả
| grade |
|---|
| An |
| Bình |
| Chi |
| Dung |
| Huy |
| Lan |
Kết quả chỉ có một cột tên grade, nhưng các ô chứa tên An, Bình và những học viên khác. SQLite hiểu grade là bí danh của name khi không có dấu phẩy. Câu lệnh không báo lỗi nên bạn dễ bỏ sót việc chọn sai cột. Muốn lấy hai cột, hãy viết SELECT name, grade.
Tính số dự kiến trên từng dòng
Người phụ trách quà muốn xem số xu của mỗi bạn nếu được thêm 10 xu. Đây là câu hỏi giả định để lập kế hoạch. Bạn cần số hiện tại bên cạnh số dự kiến để người đọc phân biệt được hai đại lượng.
Biểu thức (expression) là phần tạo ra một giá trị, chẳng hạn coins + 10. SQLite tính biểu thức bằng dữ liệu của từng dòng. Bạn dùng AS để cột tính có một tiêu đề dễ đọc:
Dữ liệu đầu vào
students6 dòng| id | name | coins |
|---|---|---|
| 1 | An | 120 |
| 2 | Bình | 90 |
| 3 | Chi | 180 |
| 4 | Dung | 60 |
| 5 | Huy | 180 |
| 6 | Lan | 150 |
Câu lệnh
SELECT id, name, coins,
coins + 10 AS after_bonus
FROM students;Kết quả
| id | name | coins | after_bonus |
|---|---|---|---|
| 1 | An | 120 | 130 |
| 2 | Bình | 90 | 100 |
| 3 | Chi | 180 | 190 |
| 4 | Dung | 60 | 70 |
| 5 | Huy | 180 | 190 |
| 6 | Lan | 150 | 160 |
Dòng của An có coins bằng 120 và after_bonus bằng 130. Dòng của Bình có hai giá trị tương ứng là 90 và 100. Máy cộng 10 cho từng giá trị nguồn, không cộng 10 vào một tổng chung.
Bạn có thể bỏ cột coins khỏi kết quả nhưng phép tính vẫn đọc được cột đó từ bảng nguồn. Tuy nhiên, khi đang giải thích một phép tính, giữ cả đầu vào giúp người đọc kiểm tra dễ hơn. Tiêu đề after_bonus nói rõ đây là dự kiến sau thưởng.
NguồnĐọc coins đang lưuBiểu thứcTính coins + 10Kết quảHiện cột after_bonus
| Ký hiệu | Cách đọc | Chẳng hạn |
|---|---|---|
+ | Cộng | coins + 10 |
- | Trừ | coins - 10 |
* giữa hai giá trị | Nhân | coins * 2 |
(...) | Tính phần trong ngoặc trước | (coins + 10) * 2 |
Khi có cả nhân và cộng, máy thực hiện nhân trước. Nếu kế hoạch là nhân đôi số hiện có rồi cộng 10, hãy kiểm tra bằng ví dụ sau. Cột cuối giúp so sánh với kế hoạch cộng trước rồi nhân đôi:
Dữ liệu đầu vào
students6 dòng| name | coins |
|---|---|
| An | 120 |
| Bình | 90 |
| Chi | 180 |
| Dung | 60 |
| Huy | 180 |
| Lan | 150 |
Câu lệnh
SELECT name, coins,
coins * 2 + 10 AS double_then_add,
(coins + 10) * 2 AS add_then_double
FROM students;Kết quả
| name | coins | double_then_add | add_then_double |
|---|---|---|---|
| An | 120 | 250 | 260 |
| Bình | 90 | 190 | 200 |
| Chi | 180 | 370 | 380 |
| Dung | 60 | 130 | 140 |
| Huy | 180 | 370 | 380 |
| Lan | 150 | 310 | 320 |
Với An, hai cột dự kiến là 250 và 260. Ngoặc làm khoản cộng thêm cũng được nhân đôi trong cột cuối. Bạn cần chọn công thức theo lời yêu cầu, chứ không chọn công thức nào cho số đẹp hơn.
Để kiểm lại số đang lưu, hãy đọc cột gốc bằng một truy vấn mới:
Dữ liệu đầu vào
students6 dòng| name | coins |
|---|---|
| An | 120 |
| Bình | 90 |
| Chi | 180 |
| Dung | 60 |
| Huy | 180 |
| Lan | 150 |
Câu lệnh
SELECT name, coins
FROM students;Kết quả
| name | coins |
|---|---|
| An | 120 |
| Bình | 90 |
| Chi | 180 |
| Dung | 60 |
| Huy | 180 |
| Lan | 150 |
Các số hiện tại vẫn giữ nguyên. Vì vậy, bảng kế hoạch và bảng số dư có thể khác nhau mà không mâu thuẫn. Điều cần làm là ghi tiêu đề rõ để người nhận không coi một dự kiến là phần thưởng đã thực hiện.
Phân biệt tên cột, chữ cố định và dấu sao
Bạn có thể thêm một nhãn chung vào báo cáo, chẳng hạn chữ Học viên ở mỗi dòng. Chuỗi chữ (string) là một giá trị văn bản. Trong SQL, nháy đơn bao quanh chuỗi cố định; tên cột thông thường được viết trực tiếp.
Câu sau đặt tên thật cạnh một chữ giống tên cột để thấy sự khác biệt:
Dữ liệu đầu vào
students6 dòng| name |
|---|
| An |
| Bình |
| Chi |
| Dung |
| Huy |
| Lan |
Câu lệnh
SELECT name AS student_name,
'name' AS label
FROM students;Kết quả
| student_name | label |
|---|---|
| An | name |
| Bình | name |
| Chi | name |
| Dung | name |
| Huy | name |
| Lan | name |
Cột student_name thay đổi theo từng học viên. Cột label chứa chữ name ở mọi dòng vì máy đọc nội dung trong nháy đơn như một giá trị cố định. Nếu báo cáo toàn chữ name, hãy kiểm tra dấu nháy trước khi nghi ngờ dữ liệu nguồn.
Nháy đơn cũng cần khi nhãn có khoảng trắng, chẳng hạn 'Học viên'. Bạn không phải tạo một cột lưu nhãn chỉ để hiển thị nó. Một biểu thức cố định vẫn được tạo cho từng dòng đang đọc.
| Cách viết | Máy đọc thành |
|---|---|
name | Giá trị ở cột tên của từng dòng |
'name' | Chữ name giống nhau ở mọi dòng |
name AS label | Giá trị tên, với tiêu đề label |
Khi mới xem một bảng nhỏ, bạn có thể cần nhìn mọi cột. Dấu * đứng ở vị trí danh sách cột nghĩa là lấy toàn bộ cột. Hãy chạy một lần để so với bản chỉ chọn tên và khối:
Dữ liệu đầu vào
students6 dòng| id | name | grade | city | coins | mentor |
|---|---|---|---|---|---|
| 1 | An | 6 | Hà Nội | 120 | Cô Mai |
| 2 | Bình | 7 | Đà Nẵng | 90 | NULL |
| 3 | Chi | 8 | Hà Nội | 180 | Thầy Nam |
| 4 | Dung | 6 | Huế | 60 | NULL |
| 5 | Huy | 9 | Cần Thơ | 180 | Cô Mai |
| 6 | Lan | 7 | Hà Nội | 150 | Thầy Nam |
Câu lệnh
SELECT *
FROM students;Kết quả
| id | name | grade | city | coins | mentor |
|---|---|---|---|---|---|
| 1 | An | 6 | Hà Nội | 120 | Cô Mai |
| 2 | Bình | 7 | Đà Nẵng | 90 | NULL |
| 3 | Chi | 8 | Hà Nội | 180 | Thầy Nam |
| 4 | Dung | 6 | Huế | 60 | NULL |
| 5 | Huy | 9 | Cần Thơ | 180 | Cô Mai |
| 6 | Lan | 7 | Hà Nội | 150 | Thầy Nam |
Kết quả có cả mã, tên, khối, thành phố, xu và người hướng dẫn. Trong phép tính coins * 2, dấu sao là phép nhân vì nó nằm giữa hai giá trị. Vị trí dùng quyết định ý nghĩa của ký hiệu.
Với báo cáo cần hai cột, bạn nên liệt kê đúng hai cột đó. Nếu bảng được thêm một cột trong tương lai, SELECT * cũng trả thêm cột ấy. Danh sách cột viết rõ giúp kết quả tiếp tục khớp với yêu cầu ban đầu.
Lỗi thường gặp
| Lỗi | Vì sao sai | Cách sửa |
|---|---|---|
Viết 'name' khi cần tên học viên | Nháy đơn tạo chữ cố định | Viết name để đọc cột |
| Dùng bí danh cũ như cột nguồn | Bí danh không thêm cột vào bảng | Đọc cột gốc rồi đặt AS |
| Thiếu dấu phẩy giữa các cột | Tên sau có thể bị hiểu thành bí danh | Tách các cột bằng dấu phẩy, dùng AS rõ ràng |
| Coi cột dự kiến là số xu đã cộng | Biểu thức chỉ tính kết quả đọc | Đặt tên thể hiện dự kiến và đối chiếu cột gốc |
Tóm tắt
- Hãy chọn cột theo thông tin người nhận cần. Thứ tự sau
SELECTlà thứ tự cột kết quả. FROMchỉ bảng nguồn, cònASđặt tiêu đề cho một cột trong lần đọc đó.- Biểu thức được tính cho từng dòng. Kết quả tính không thay số đang lưu.
- Nháy đơn tạo chữ cố định. Dấu
*trong danh sách cột lấy mọi cột của bảng.
Kiểm tra nhanh
Đọc thêm
- SQLite: cách SELECT tạo các cột kết quả — xem vai trò của danh sách biểu thức.
- SQLite: biểu thức và thứ tự toán tử — tra phép cộng, nhân và chuỗi chữ.