Khóa học
Trong hướng dẫn này, bạn sẽ tập trung vào SQL theo chuẩn ANSI (American National Standards Institute) chạy được trên mọi hệ quản trị như Oracle, MySQL, Microsoft SQL Server, v.v.! Hãy bắt đầu với giới thiệu về SQL (Structured Query Language) và lý do một nhà khoa học dữ liệu cần đến nó.
SQL và Khoa học Dữ liệu
Trong phần này, bạn sẽ thấy vì sao một nhà khoa học dữ liệu nên học SQL. Hãy xem SQL sẽ giúp ích thế nào cho sự nghiệp của bạn:
- SQL đã trở thành yêu cầu trong hầu hết các công việc khoa học dữ liệu như: nhà phân tích dữ liệu, nhà phát triển BI (Business Intelligence), lập trình viên, lập trình viên cơ sở dữ liệu. SQL cho phép bạn giao tiếp với cơ sở dữ liệu và làm việc với dữ liệu của mình.
- Nếu bạn từng dùng phần mềm như Tableau hay các công cụ báo cáo/ trực quan hóa khác, bạn sẽ thấy cách kết nối dự án với cơ sở dữ liệu rồi kéo thả biểu đồ vào báo cáo chỉ bằng việc chỉ định trường; phần mềm làm phần còn lại. Khi bạn kéo thả thuộc tính dữ liệu hay dùng giao diện đồ họa để thao tác trong một cú nhấp, đằng sau chính là SQL đang chạy để tương tác với cơ sở dữ liệu. Học SQL giúp bạn tương tác trực tiếp với cơ sở dữ liệu.
- SQL có thể dùng với mọi ngôn ngữ lập trình ứng dụng như PHP, Java. Bạn có thể tạo trực quan hóa dữ liệu của riêng mình bằng cách tích hợp SQL vào ứng dụng hoặc lấy dữ liệu từ cơ sở dữ liệu và chuyển sang định dạng XML, JSON để dùng trong web service hoặc API.
- Các cơ sở dữ liệu đã phát triển qua nhiều năm; khi Big Data trở nên phổ biến và dữ liệu len lỏi đời sống hằng ngày, các cơ sở dữ liệu NoSQL cũng ngày càng thịnh hành. Học SQL sẽ giúp bạn xây nền tảng vững chắc về cơ sở dữ liệu và hiểu khi nào nên dùng cơ sở dữ liệu có cấu trúc, khi nào nên dùng NoSQL, cũng như trân trọng sự khác biệt của chúng.
Tại đây tôi sẽ điểm qua phần giới thiệu và thuật ngữ dùng trong SQL và cơ sở dữ liệu để giúp bạn học code nhanh hơn! Nếu bạn đã biết cơ sở dữ liệu quan hệ là gì và SQL là gì, bạn có thể chuyển đến phần mã.
Giới thiệu về SQL và Cơ sở dữ liệu
Cơ sở dữ liệu là một tập hợp thông tin được tổ chức. Để quản lý cơ sở dữ liệu, chúng ta cần Hệ quản trị Cơ sở dữ liệu (DBMS). DBMS là chương trình lưu trữ, truy xuất và chỉnh sửa dữ liệu trong cơ sở dữ liệu theo yêu cầu.
Theo thời gian có nhiều loại cơ sở dữ liệu: phân cấp, mạng, quan hệ và nay là NoSQL. Cơ sở dữ liệu quan hệ là một tập các quan hệ hay các bảng hai chiều.

Sau đây là các thuật ngữ dùng trong RDBMS:
| Thuật ngữ | Mô tả |
|---|---|
| Bảng (Table) | Bảng là cấu trúc lưu trữ cơ bản của RDBMS. Một bảng lưu toàn bộ dữ liệu cần thiết về một thực thể ngoài đời. Ví dụ: Nhân viên. |
| Hàng đơn hay Bộ (Tuple) | Biểu diễn mọi dữ liệu cần thiết cho một nhân viên cụ thể. Mỗi hàng trong bảng có thể được nhận diện bởi Khóa chính, không cho phép trùng lặp hàng. |
| Cột hay Thuộc tính | Thường chỉ một đặc điểm của thực thể |
| Khóa chính (Primary Key) | Một trường xác định duy nhất một hàng |
| Khóa ngoại (Foreign Key) | Một cột xác định mối liên hệ giữa các bảng. Khóa ngoại tham chiếu đến Khóa chính ở bảng khác. |
Bạn có thể liên kết nhiều bảng bằng Khóa chính và Khóa ngoại. Mỗi hàng trong cơ sở dữ liệu quan hệ được định danh duy nhất bằng Khóa chính (PK). Bạn có thể tham chiếu sang bảng khác bằng Khóa ngoại (FK). Ví dụ:

Cơ sở dữ liệu quan hệ có thể truy cập bằng Structured Query Language hay SQL. Mọi hệ quản trị sẽ hỗ trợ SQL chuẩn ANSI, đồng thời có cú pháp riêng cho một số thao tác. Trong hướng dẫn này, bạn sẽ học SQL ANSI để có thể làm việc với mọi cơ sở dữ liệu. ANSI SQL có thể chia thành năm phần. Tôi sẽ liệt kê cả năm nhưng tại đây chỉ hai phần liên quan là Truy xuất dữ liệu và DML:
- Truy xuất dữ liệu:
- Select.
- Ngôn ngữ thao tác dữ liệu (DML):
- Insert, Update, Delete, Merge
- Ngôn ngữ định nghĩa dữ liệu (DDL):
- Create, Alter, Drop, Rename, Truncate.
- Ngôn ngữ điều khiển dữ liệu (DCL):
- Grant, Revoke.
- Kiểm soát giao dịch:
- Commit, Rollback, Savepoint.
Có nhiều nhà cung cấp RDBMS. Phổ biến nhất gồm:
- Oracle (Oracle Corporation)
- Microsoft SQL Server (Microsoft)
- MySQL (Oracle Corporation)
- PostgreSQL (PostgreSQL Global Development Group)
- SQLite (Phát triển bởi D. Richard Hipp)
Vậy bạn chạy câu lệnh SQL ở đâu? Có thể là:
- Một phần mềm báo cáo cho phép đọc từ cơ sở dữ liệu và xem dữ liệu (Ví dụ: Tableau, Microsoft BI)
- Một GUI quản trị cơ sở dữ liệu (ví dụ: TOAD, SQL Developer cho Oracle, phpMyAdmin cho MySQL)
- Một giao diện console trực tiếp đến cơ sở dữ liệu (Ví dụ: SQL*Plus cho Oracle)
Nếu bạn có thông tin đăng nhập vào cơ sở dữ liệu, bạn có thể xem các đối tượng cơ sở dữ liệu bằng truy vấn hoặc GUI tùy theo nhà cung cấp.
Vậy là đủ! Bắt đầu học SQL nào...
Kiểu dữ liệu trong SQL
Mỗi cột trong cơ sở dữ liệu có tên, kiểu dữ liệu và đôi khi kèm kích thước. Nhà phát triển cơ sở dữ liệu sẽ thiết kế và quyết định dùng kiểu dữ liệu nào theo yêu cầu và khối lượng dữ liệu.
Là nhà khoa học dữ liệu, bạn cần quen với các kiểu dữ liệu vì chúng giúp bạn dùng đúng hàm và viết truy vấn chính xác. Mỗi kiểu cột đều có kiểu dữ liệu tương ứng như tên người, đoạn văn bản, số, ảnh lưu trong cơ sở dữ liệu, v.v.
Dưới đây là các kiểu dữ liệu cơ bản cho Oracle Server, SQL Server và MySQL:

Đọc thêm:
SQL và Báo cáo dữ liệu
Trong toàn bộ hướng dẫn này, dùng lược đồ cơ sở dữ liệu mẫu sau:
Giả sử có cơ sở dữ liệu với hai bảng emp lưu dữ liệu nhân viên và bảng dept lưu thông tin phòng ban.
Bảng emp có số nhân viên (empno), tên (ename), lương (sal), hoa hồng (comm), chức danh (job), mã quản lý (mgr), ngày vào làm (hiredate) và số phòng ban (deptno). Vì Quản lý cũng là nhân viên và có số nhân viên, nên mgr là một trong các empno có job là "MANAGER".
Bảng dept có số phòng ban (deptno), tên phòng ban (dname) và địa điểm (loc).

Lưu ý, các cơ sở dữ liệu dùng định dạng ngày khác nhau. Ở đây DD-MON-YY là định dạng mặc định của Oracle. Mặc định của Microsoft SQL Server và MySQL là YYYY-MM-DD.
Bảng của bạn có thể khác, vậy nên bạn chỉ cần điều chỉnh theo tên bảng và tên thuộc tính của mình. Trong hướng dẫn này, bạn chỉ đọc từ cơ sở dữ liệu, không ghi, cập nhật hay tạo bảng/đối tượng mới. Vậy nên không lo mất mát hay thay đổi dữ liệu!
Thông tin: Schema là tập hợp các đối tượng như bảng, hàm, thủ tục, view thuộc về một người dùng
Trong lược đồ trên, bạn thấy bảng emp có sáu thuộc tính cho thực thể Nhân viên. Bảng dept có ba thuộc tính cho thực thể Phòng ban.
Truy xuất dữ liệu bằng câu lệnh SELECT
Câu lệnh SELECT truy xuất thông tin từ cơ sở dữ liệu. Với SELECT, bạn có thể:
1. Phép chiếu (Projection): chọn các cột trong bảng bạn muốn trả về. Bạn có thể chọn ít hay nhiều cột tùy cần.
2. Phép chọn (Selection): chọn các hàng trong bảng bạn muốn trả về theo điều kiện.
Bạn có thể dùng nhiều tiêu chí để giới hạn hàng hiển thị.
3. Phép nối (Joining): kết hợp dữ liệu lưu ở các bảng khác nhau bằng cách tạo liên kết giữa chúng.
Câu lệnh SELECT cơ bản cho phép bạn chỉ định cần cột nào từ bảng nào. Mệnh đề SELECT chỉ định cột, biểu thức và mệnh đề FROM chỉ định bảng lấy dữ liệu.
Ví dụ, Tên và chức danh của tất cả nhân viên: SELECT ename, job FROM employee; Truy vấn trên sẽ cho kết quả sau dựa trên lược đồ đã bàn:
| ename | job |
|---|---|
| A | Salesman |
| B | Manager |
| C | Manager |
Để chọn tất cả thuộc tính và tất cả hàng của bảng dùng toán tử *:
SELECT *
FROM employee;
The output will be:
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
7369 SMITH CLERK 7902 17-DEC-80 800 20
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
7566 JONES MANAGER 7839 02-APR-81 2975 20
7698 BLAKE MANAGER 7839 01-MAY-81 2850 30
Một vài mẹo viết câu lệnh SQL:
- SQL không phân biệt hoa thường
- Viết các mệnh đề trên dòng riêng để dễ đọc
- Bạn có thể viết SQL trên một hoặc nhiều dòng
Bạn cũng có thể tạo biểu thức dùng các toán tử +,-,/,* trên dữ liệu ngày và số để tạo ra dữ liệu cần. Ví dụ, cần tính 20% lương của tất cả nhân viên. Truy vấn như sau:
SELECT ename, sal*(20/100)
FROM employee;
Output:
ENAME SAL*(20/100)
---------- ------------
SMITH 160
ALLEN 320
WARD 250
JONES 595
BLAKE 570
Thông tin:
- Dùng ngoặc để làm rõ biểu thức
- Chia và nhân có độ ưu tiên cao hơn cộng và trừ
- Nếu cùng độ ưu tiên, biểu thức được tính từ trái sang phải
Giá trị NULL được xử lý khác nhau trong cơ sở dữ liệu. NULL ngụ ý giá trị không biết. Mọi phép toán với NULL đều cho kết quả NULL. Các hệ quản trị khác nhau có hàm xử lý null khác nhau. Có một hàm chung dùng trong MySQL, Microsoft SQL Server và Oracle để xử lý NULL.
SELECT ename, sal+COALESCE(comm,0)
FROM employee;
Output:
ENAME SAL+COALESCE(COMM,0)
---------- --------------------
SMITH 800
ALLEN 1900
WARD 1750
JONES 2975
BLAKE 2850
Bí danh cột và Nối chuỗi
Bạn thấy trong các kết quả trên, tên cột giống hệt trường trong cơ sở dữ liệu hoặc biểu thức bạn chọn. Đôi khi, khi tạo báo cáo bạn muốn đặt tiêu đề riêng. Có thể làm bằng bí danh.
SELECT ename AS "Emp Name", sal*(20/100) as "20% of Salary"
FROM employee;
Output:
Emp Name 20% of Salary
---------- ------------
SMITH 160
ALLEN 320
WARD 250
JONES 595
BLAKE 570
Khi đặt bí danh có khoảng trắng, bạn phải dùng dấu ngoặc kép. Nếu không có khoảng trắng thì không cần. Đôi khi bạn cũng có thể bỏ từ khóa AS.
Bạn có thể định dạng đầu ra bằng cách nối chuỗi. Bạn có thể thêm câu chữ của riêng mình vào kết quả dùng hàm CONCAT hoặc toán tử như || hoặc + tùy hệ quản trị:
- Oracle hỗ trợ CONCAT() và || nhưng CONCAT() chỉ nhận hai đối số. Bạn phải lồng CONCAT().
- MySQL dùng CONCAT()
- Microsoft SQL Server dùng toán tử '+' và CONCAT().
Oracle: SELECT '20% of salary of '||ename||' is '||sal*(20/100) as "20% of salary" FROM employee;
SELECT CONCAT(CONCAT('20% of salary of',ename),CONCAT(' is ',sal(20/100))) as "20% of salary" FROM employee; MySQL và Microsoft SQL Server: SELECT CONCAT('20% of salary of ',ename,' is ',sal(20/100)) as "20% of salary" FROM employee; Tất cả sẽ cho cùng kết quả:
20% of salary
-----------------------------------------------------------------------
20% of salary of SMITH is 160
20% of salary of ALLEN is 320
20% of salary of WARD is 250
20% of salary of JONES is 595
20% of salary of BLAKE is 570
Loại bỏ hàng lặp bằng DISTINCT
SELECT deptno
FROM employee;
Above query will result in:
DEPTNO
----------
20
30
30
20
30
Ở đây deptno 20 và 30 lặp lại. Bạn có thể loại bỏ các hàng như vậy bằng từ khóa DISTINCT trong mệnh đề SELECT.
SELECT distinct ename, deptno, job
FROM employee;
DEPTNO
----------
30
20
Giới hạn và Sắp xếp dữ liệu
Mệnh đề WHERE dùng để lọc dữ liệu theo điều kiện.
Tìm tất cả nhân viên có job là CLERK:
SELECT ename, job
FROM employee
WHERE job='CLERK';
ENAME JOB
---------- ---------
SMITH CLERK
Bạn có thể lọc kết quả với các điều kiện khác nhau. Cho việc này dùng các toán tử, ký hiệu điều kiện và từ khóa cụ thể:

Cách dùng =,<>,!=,>=,<=,>,< đơn giản như trong truy vấn trên dùng =.
Cú pháp AND & OR: SELECT column1, column2,.. FROM table_name WHERE condition1 AND condition2 AND condition 3...;
SELECT column1, column2,.. FROM table_name WHERE condition1 OR condition2 OR condition 3...; Tìm tên nhân viên có job là MANAGER và thuộc phòng ban 30:
SELECT ename
FROM employee
WHERE job='MANAGER' AND deptno=30;
ENAME
----------
BLAKE
SELECT ename
FROM employee
WHERE job='MANAGER' OR deptno=30;
ENAME
----------
ALLEN
WARD
JONES
BLAKE
Cú pháp NOT: SELECT column1, column2, ... FROM table_name WHERE NOT condition; Tìm tất cả nhân viên có job không phải SALESMAN:
SELECT ename, job
from employee
WHERE NOT job='SALESMAN';
ENAME JOB
---------- ---------
SMITH CLERK
JONES MANAGER
BLAKE MANAGER
Bạn có thể tạo điều kiện phức hợp dùng cả AND, OR và NOT. Độ ưu tiên là:
- NOT
- AND
- OR
Tìm tất cả nhân viên có job không phải CLERK và thuộc phòng ban 20:
SELECT ename, job
from employee
WHERE NOT job='SALESMAN' AND sal>800;
ENAME JOB
---------- ---------
JONES MANAGER
BLAKE MANAGER
Ở đây NOT được thực thi trước, sau đó đến AND.
Các toán tử điều kiện hữu ích khác:
BETWEEN...AND:
SELECT *
FROM employee
WHERE sal BETWEEN 1000 AND 2000;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
LIKE:
LIKE dùng hai ký tự đại diện: phần trăm % và gạch dưới _ để biểu diễn số lượng ký tự trong mẫu.
- % nghĩa là không, một hoặc nhiều ký tự
- %M%: Khớp chuỗi có M ở bất kỳ vị trí nào
- M%: Khớp giá trị có M ở đầu
- %M: Khớp giá trị có M ở cuối
- M%A: Bắt đầu bằng M và kết thúc bằng A
Mẫu có phân biệt hoa thường.
- _ chỉ số ký tự không biết trước hoặc sau ký tự đã biết. Mỗi gạch dưới là một ký tự.
- _r%: Khớp giá trị có r ở vị trí thứ hai.
Lấy tên tất cả nhân viên có tên bắt đầu bằng 'B':
SELECT *
FROM employee
WHERE ename LIKE 'B%';
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
7698 BLAKE MANAGER 7839 01-MAY-81 2850 30
Lấy tên tất cả nhân viên có tên bắt đầu bằng 'A' và có 'E' ở bất kỳ vị trí nào sau 'A':
SELECT *
FROM employee
WHERE ename LIKE 'A%E%';
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
IN(value1,value2, value3,..):
Hàm IN() có thể nhận một, hai hoặc nhiều giá trị và cho phép bạn khớp một cột với các giá trị trong ngoặc ở mệnh đề WHERE:
SELECT ename, job, hiredate
FROM employee
WHERE job IN ('CLERK','SALESMAN');
ENAME JOB HIREDATE
---------- --------- ---------
SMITH CLERK 17-DEC-80
ALLEN SALESMAN 20-FEB-81
WARD SALESMAN 22-FEB-81
Bạn cũng có thể dùng câu lệnh SELECT trong IN() để trả về một số giá trị. Ví dụ:
SELECT ename, job, hiredate
FROM employee
WHERE deptno IN (select deptno FROM department WHERE loc='CHICAGO');
ENAME JOB HIREDATE
---------- --------- ---------
ALLEN SALESMAN 20-FEB-81
WARD SALESMAN 22-FEB-81
BLAKE MANAGER 01-MAY-81
Câu SELECT trong IN() cũng gọi là truy vấn con (subquery). Sẽ nói thêm ở phần sau!
IS NULL:
IS NULL dùng để kiểm tra giá trị NULL ở một thuộc tính. Ví dụ, tìm tất cả nhân viên không có hoa hồng:
SELECT ename, job, sal
FROM employee
WHERE comm IS NULL;
ENAME JOB SAL
---------- --------- ----------
SMITH CLERK 800
JONES MANAGER 2975
BLAKE MANAGER 2850
Nếu muốn lấy tên nhân viên có nhận hoa hồng, dùng IS NOT NULL:
SELECT ename, job, sal, comm
FROM employee
WHERE comm IS NOT NULL;
ENAME JOB SAL COMM
---------- --------- ---------- ----------
ALLEN SALESMAN 1600 300
WARD SALESMAN 1250 500
Để lọc kết quả theo cột ngày, bạn phải dùng định dạng ngày mặc định. Nếu dùng định dạng khác, cần áp dụng hàm ngày tháng sẽ nói sau. Tìm tất cả nhân viên được tuyển sau 21 February 1981:
(Ở đây dùng định dạng mặc định của Oracle)
SELECT ename, job, sal, comm
FROM employee
WHERE hiredate>'21-FEB-81';
ENAME JOB SAL COMM
---------- --------- ---------- ----------
WARD SALESMAN 1250 500
JONES MANAGER 2975
BLAKE MANAGER 2850
Bạn có thể tạo biểu thức điều kiện phức tạp bằng cách kết hợp các toán tử trên, nhưng cần chú ý độ ưu tiên. Độ ưu tiên là thứ tự toán tử được đánh giá. Dưới đây là các quy tắc độ ưu tiên cho các hệ quản trị khác nhau:
- Độ ưu tiên toán tử Microsoft Transact-SQL
- Độ ưu tiên điều kiện Oracle 10g
- Độ ưu tiên toán tử Oracle MySQL 9
- Độ ưu tiên toán tử PostgreSQL
- Độ ưu tiên toán tử SQLite
Có hai hàm hữu ích: ANY(), ALL() có thể dùng trong điều kiện. Ví dụ:
SELECT ename, job, sal, comm FROM employee WHERE deptno=ANY(SELECT deptno from dept WHERE loc='NEW YORK');
SELECT ename, job, sal, comm FROM employee WHERE deptno=ALL(SELECT deptno from dept WHERE dname='SALES');
Lưu ý việc dùng truy vấn con ở ví dụ trên. Bạn sẽ học thêm về subquery sau.
Sắp xếp kết quả bằng ORDER BY
Bạn có thể sắp xếp tăng (ASC) hoặc giảm (DESC) theo bất kỳ thuộc tính nào hoặc nhiều thuộc tính. Bạn cũng có thể sắp theo bí danh trong SELECT:
SELECT ename, job, sal, comm
FROM employee
WHERE hiredate>'21-FEB-81'
ORDER BY sal desc;
ENAME JOB SAL COMM
---------- --------- ---------- ----------
JONES MANAGER 2975
BLAKE MANAGER 2850
WARD SALESMAN 1250 500
Lưu ý: Thứ tự mặc định là tăng dần (ASC), bạn không cần chỉ định ASC.
SELECT ename, job, sal, comm
FROM employee
WHERE hiredate>'21-FEB-81'
ORDER BY sal;
ENAME JOB SAL COMM
---------- --------- ---------- ----------
WARD SALESMAN 1250 500
BLAKE MANAGER 2850
JONES MANAGER 2975
Bạn có thể chỉ định nhiều cột trong ORDER BY, sẽ được áp dụng theo thứ tự đã nêu. Ví dụ, sắp nhân viên theo deptno tăng dần rồi tên giảm dần:
SELECT ename, job, sal, comm, deptno
FROM employee
WHERE hiredate>'21-FEB-81'
ORDER BY deptno ASC, ename DESC;
ENAME JOB SAL COMM DEPTNO
---------- --------- ---------- ---------- ----------
JONES MANAGER 2975 20
WARD SALESMAN 1250 500 30
BLAKE MANAGER 2850 30
Dùng hàm đơn dòng để tùy chỉnh đầu ra
Có vô số hàm trong RDBMS giúp bạn làm các tác vụ thường gặp như lấy độ dài chuỗi, nối chuỗi, định dạng, toán học, v.v. Có hai loại hàm dòng trong SQL:
- Hàm đơn dòng
- Hàm đa dòng
Hàm đơn dòng:
Các hàm này áp dụng trên từng hàng và trả về kết quả cho mỗi hàng. CONCAT() là một hàm xử lý ký tự đơn dòng. Chúng có thể dùng trong SELECT, WHERE và ORDER BY. Có các nhóm hàm đơn dòng sau trong mọi RDBMS:
- Hàm xử lý ký tự
- Hàm Ngày và Giờ
- Hàm Số
- Hàm Chuyển đổi
Các cơ sở dữ liệu khác nhau có thể đặt tên hàm khác nhau cho cùng một chức năng. Ở đây tôi sẽ nói các hàm chung hữu ích giữa Microsoft SQL Server, Oracle và MySQL. Một số bạn đã thấy ở phần trên. Cuối phần sẽ có link danh sách đầy đủ để bạn luyện thêm.
Lần lượt theo từng nhóm:
Hàm xử lý ký tự
LOWER(): Chuyển chuỗi thành chữ thường.
SELECT lower(ename) as ename
FROM employee;
ENAME
----------
smith
allen
ward
jones
blake
UPPER(): Chuyển chuỗi thành chữ hoa.
SELECT upper(ename) as ename
FROM employee;
ENAME
----------
SMITH
ALLEN
WARD
JONES
BLAKE
SUBSTR()[Oracle, MySQL]: Trả về chuỗi con theo chỉ định SUBSTR(string, start-position,length)
SUBSTRING()[SQL Server]: Trả về chuỗi con theo chỉ định SUBSTRING(string, start-position,length).
SELECT SUBSTR(ename,2,3) as substr_ename FROM employee;
Với SQL Server chỉ cần đổi tên hàm thành SUBSTRING.
SUBSTR_ENAME ------------ MIT LLE ARD ONE LAK
LENGTH()[Oracle, MySQL]: Trả về độ dài chuỗi trong ngoặc
LEN()[SQL Server]: Trả về độ dài chuỗi trong ngoặc
SELECT LENGTH(ename) as len_ename FROM employee;
Với SQL Server chỉ cần đổi tên hàm thành LEN.
LEN_ENAME
----------
5
5
4
5
5
Các hàm như đệm chuỗi bên trái/phải, thay thế... có khác nhau về cú pháp giữa các hệ. Danh sách hàm Ký tự và Chuỗi cho ba hệ:
Hàm Số
| Tên hàm | Chức năng |
|---|---|
| ROUND(m,n): | Làm tròn giá trị m đến n chữ số thập phân. |
| ABS(m,n): | Trả về giá trị tuyệt đối của một số |
| FLOOR(n): | FLOOR trả về số nguyên lớn nhất nhỏ hơn hoặc bằng n. |
| MOD(m,n): | Trả về phần dư của phép chia m cho n (không có trong SQL Server nhưng dùng toán tử %: 35 % 6) |
Oracle:
SELECT ROUND(45.926,2),MOD(11,5),FLOOR(34.4),ABS(-24) from dual;
OUTPUT:
ROUND(45.926,2) MOD(11,5) FLOOR(34.4) ABS(-24)
--------------- ---------- ----------- ----------
45.93 1 34 24
MySQL:
SELECT ROUND(45.926,2),MOD(11,5),FLOOR(34.4),ABS(-24);
SQL Server:
SELECT ROUND(45.926,2) as round,11%5 as mod, FLOOR(34.4) as floor,ABS(-24) as abs;
Danh sách hàm Số cho ba hệ:
Hàm Chuyển đổi
Hàm chuyển đổi dùng để đổi một kiểu dữ liệu sang kiểu khác. Hàm chuyển đổi khác nhau giữa các máy chủ. Ở đây là ví dụ truy vấn Oracle dùng hàm to_char. Điều này giúp bạn hiểu cách dùng hàm chuyển đổi để tùy chỉnh đầu ra. Định dạng ngày mặc định của Oracle là DD-MON-YY
SELECT ename, to_char(hiredate,'DD, MONTH YYYY') as Hiredate, to_char(hiredate,'DY') as Day
from employee;
ENAME Hiredate DAY
---------- -------------------------------------------- ------------
SMITH 17,DECEMBER 1980 WED
ALLEN 20,FEBRUARY 1981 FRI
WARD 22,FEBRUARY 1981 SUN
JONES 02,APRIL 1981 THU
BLAKE 01,MAY 1981 FRI
Có rất nhiều hàm chuyển đổi cho mỗi hệ. Đọc thêm và khám phá tại các liên kết sau:
Hàm Ngày và Giờ
Hàm ngày giờ cho phép bạn thao tác ngày như cộng ngày, tính số tháng giữa hai ngày, v.v. Những hàm này hữu ích khi tạo báo cáo. Hàm ngày tháng cũng khác nhau giữa các hệ. Một hàm có thể có tên khác ở hệ khác. Ở đây bạn sẽ xem vài ví dụ và sau đó là các liên kết tới hàm ngày giờ của các hệ phổ biến: Oracle, SQL Server và MySQL. Hãy thử các ví dụ này trên hệ của bạn!

Nhóm kết quả SQL của bạn
Các hàm nhóm hay hàm đa dòng áp dụng trên nhóm và trả về một kết quả cho mỗi nhóm. Bạn sẽ cần hàm nhóm khi muốn tìm những thông tin như tổng doanh số theo quý, giá trung bình của sản phẩm trong một khoảng thời gian, khoản đầu tư cao nhất công ty nhận được trong tháng này, v.v.
Báo cáo dữ liệu tổng hợp bằng hàm nhóm
Mệnh đề GROUP BY dùng để nhóm kết quả, thường đi kèm các hàm như COUNT, MAX, MIN, AVG và SUM. Cú pháp GROUP BY:
SELECT column_name(s) FROM table_name WHERE condition GROUP BY column_name(s) HAVING condition ORDER BY column_name(s);
Lưu ý một số điểm với GROUP BY:
- Không thể dùng bí danh trong GROUP BY
- Mệnh đề WHERE luôn đứng trước GROUP BY
- Mệnh đề HAVING đứng sau GROUP BY và áp điều kiện lên các hàm nhóm.
- Mệnh đề ORDER BY luôn ở cuối
COUNT là hàm nhóm đếm số hàng theo điều kiện hoặc không điều kiện. COUNT bỏ qua giá trị null.
Đếm tất cả nhân viên có tên bắt đầu bằng 'A':
SELECT count(ename)
FROM employee
WHERE ename LIKE 'A%';
Output:
COUNT(ENAME)
------------
1
Tìm tổng lương, lương trung bình, lương thấp nhất và cao nhất trong bảng employee:
SELECT sum(sal) as "TOTAL SAL", avg(sal) as "AVG SAL", min(sal) as "MIN SAL", max(sal) as "MAX SAL"
FROM employee;
TOTAL SAL AVG SAL MIN SAL MAX SAL
---------- ---------- ---------- ----------
9475 1895 800 2975
Bạn có thể nhóm kết quả trên theo từng phòng ban:
SELECT sum(sal) as "TOTAL SAL", avg(sal) as "AVG SAL", min(sal) as "MIN SAL", max(sal) as "MAX SAL", deptno
FROM employee
GROUP BY deptno;
TOTAL SAL AVG SAL MIN SAL MAX SAL DEPTNO
---------- ---------- ---------- ---------- ----------
5700 1900 1250 2850 30
3775 1887.5 800 2975 20
Bạn cũng có thể tính Phương sai và Độ lệch chuẩn bằng các hàm sau:
| Cho Oracle và MySQL | MS SQL SERVER |
|---|---|
| SELECT STDDEV(column_name) FROM table_name; | SELECT STDEV(column_name) FROM table_name; |
| SELECT VARIANCE(column_name) FROM table_name; | SELECT VAR(column_name) FROM table_name; |
Bạn có thể nhóm theo nhiều cột.
Tìm tổng lương theo từng job trong mỗi phòng ban:
SELECT sum(sal) as "TOTAL SAL", deptno, job
FROM employee
GROUP BY deptno, job;
TOTAL SAL DEPTNO JOB
---------- ---------- ---------
800 20 CLERK
2850 30 SALESMAN
2975 20 MANAGER
2850 30 MANAGER
Bạn có thể giới hạn kết quả nhóm bằng mệnh đề HAVING. Nó chỉ dùng cho điều kiện trên nhóm.
Lưu ý: Không dùng WHERE để áp điều kiện lên hàm nhóm.
SELECT sum(sal) as "TOTAL SAL", deptno, job
FROM employee
GROUP BY deptno, job
HAVING sum(sal)>1000
ORDER BY sum(sal);
TOTAL SAL DEPTNO JOB
---------- ---------- ---------
2850 30 SALESMAN
2850 30 MANAGER
2975 20 MANAGER
Hiển thị dữ liệu từ nhiều bảng
Trong phần này sẽ bàn về các kiểu join sau:
- Tích Đề-các/ Cross join
- Inner join/EquiJoin
- Natural join
- Outer Join (Trái, Phải, Đầy đủ)
- Self Join
Bạn sẽ cần tạo báo cáo lấy dữ liệu từ nhiều bảng. Xem ví dụ dưới đây:

Để tạo báo cáo như trên, bạn cần liên kết bảng employee và department và lấy dữ liệu từ cả hai. Để làm vậy, dùng Join trong SQL.
Cartesian Product/Cross Join:
Tích Đề-các hình thành khi mỗi bộ của quan hệ R kết hợp với mỗi bộ của quan hệ S.

Phép tích Đề-các còn gọi là Cross Join nhân hai bảng để tạo quan hệ gồm mọi cặp bộ có thể từ hai bảng. Nếu quan hệ R có I bộ với M thuộc tính và quan hệ S có J bộ với N thuộc tính, tích Đề-các sẽ có IxJ bộ với M+N thuộc tính. Có thể tạo tích Đề-các bằng CROSS JOIN chuẩn SQL.
SELECT empno, ename, dname
FROM employee, department;
OR
SELECT empno, ename, dname
FROM employee CROSS JOIN department;
EMPNO ENAME DNAME
---------- ---------- --------------
7369 SMITH ACCOUNTING
7499 ALLEN ACCOUNTING
7521 WARD ACCOUNTING
7566 JONES ACCOUNTING
7698 BLAKE ACCOUNTING
7369 SMITH RESEARCH
7499 ALLEN RESEARCH
7521 WARD RESEARCH
7566 JONES RESEARCH
7698 BLAKE RESEARCH
7369 SMITH SALES
EMPNO ENAME DNAME
---------- ---------- --------------
7499 ALLEN SALES
7521 WARD SALES
7566 JONES SALES
7698 BLAKE SALES
Đã chọn 15 hàng.
Vì bảng employee có 5 bộ và department có 3 bộ nên tích Đề-các có 5x3=15 hàng. Tích Đề-các sinh ra khi:
- Không dùng điều kiện join
- Điều kiện join không hợp lệ hoặc tạo chưa đúng
Khi cần dữ liệu từ hai hay nhiều bảng, tạo điều kiện join bằng các thuộc tính chung liên kết các bảng. Thường là Khóa chính và Khóa ngoại.
Tích Đề-các dùng để mô phỏng lượng dữ liệu lớn phục vụ kiểm thử.
*Inner Join/EquiJoin:
Inner Join hay Equijoin (thuật ngữ hay dùng với Oracle) sử dụng quan hệ khóa chính và khóa ngoại để nối hai hay nhiều bảng:
SELECT ename, dname
FROM employee e,department d
WHERE e.deptno=d.deptno;
OR
SELECT ename, dname
FROM employee e
JOIN department d
ON e.deptno=d.deptno;
ENAME DNAME
---------- --------------
SMITH RESEARCH
ALLEN SALES
WARD SALES
JONES RESEARCH
BLAKE SALES
Trong truy vấn trên, deptno là khóa chính ở bảng department và khóa ngoại ở bảng employee. Bạn có thể thêm điều kiện bổ sung bằng các toán tử logic như đã nêu ở phần trên.
Điểm cần nhớ về JOIN:
- Nếu cùng tên cột xuất hiện ở hơn một bảng, phải thêm tiền tố tên bảng trước tên cột. Làm vậy cũng giúp rõ ràng.
- Để nối n bảng, cần tối thiểu n-1 điều kiện join. Ví dụ, nối 4 bảng cần tối thiểu 3 join.
Bí danh bảng: Bí danh bảng như trong FROM employee e, department d nơi e và d là bí danh, giúp hệ quản trị xác định cột thuộc bảng nào, đặc biệt khi có cột trùng tên ở nhiều bảng, tránh lỗi mơ hồ. Đồng thời tiết kiệm công gõ tên bảng dài lặp đi lặp lại.
Bạn cũng có thể tạo nonequi-join, tức nối bảng dựa trên điều kiện khác dấu bằng. Xét bảng salgrade chứa thông tin bậc lương theo mức lương:

Bạn muốn tìm bậc lương của mỗi nhân viên dựa trên lương, trong đó bậc ở salgrade còn lương ở employee:
SELECT e.ename, e.sal, s.grade
FROM employee e, salgrade s
WHERE e.sal between s.losal AND s.hisal;
ENAME SAL GRADE
---------- ---------- ----------
JONES 2975 4
BLAKE 2850 4
ALLEN 1600 3
WARD 1250 2
SMITH 800 1
Ví dụ: Bạn được yêu cầu đưa ra tên nhân viên, lương, bậc và tên phòng ban. Vì lương ở bảng employee, bậc ở bảng salgrade và tên phòng ban ở bảng department, bạn sẽ cần nối ba bảng:
SELECT e.ename, e.sal, d.dname, s.grade FROM employee e, department d, salgrade s WHERE e.deptno=d.deptno AND e.sal BETWEEN s.losal AND s.hisal; Output: ENAME SAL DNAME GRADE ---------- ---------- -------------- ---------- JONES 2975 RESEARCH 4 BLAKE 2850 SALES 4 ALLEN 1600 SALES 3 WARD 1250 SALES 2 SMITH 800 RESEARCH 1
Trong ví dụ trên, có ba bảng và hai điều kiện join, một trong số đó là nonequi-join.
Natural Join:
Natural join cho phép cơ sở dữ liệu tự động nối bảng bằng cách khớp các cột trùng tên. Nếu cột trùng tên nhưng khác kiểu dữ liệu, sẽ báo lỗi.
Cú pháp: SELECT FROM table1 NATURAL JOIN table2; SELECT FROM employee NATURAL JOIN department; Vì natural join tự tìm cột khớp, có thể có hơn một cột trùng tên nhưng khác kiểu dữ liệu gây lỗi. Do đó dùng mệnh đề USING để chỉ rõ cột dùng equi join.
Lưu ý: NATURAL JOIN và USING là hai mệnh đề riêng biệt dùng độc lập. Không dùng cùng nhau; chúng loại trừ nhau.
SELECT e.ename, d.dname, e.sal FROM employee e JOIN department d USING (deptno) WHERE deptno=20; output: ENAME DNAME SAL ---------- -------------- ---------- SMITH RESEARCH 800 JONES RESEARCH 2975
Các cột trong mệnh đề USING không được dùng tiền tố tên bảng ở bất kỳ đâu trong câu lệnh SQL. Ví dụ sau là sai:
SELECT e.ename, d.dname, e.sal FROM employee e JOIN department d USING (d.deptno) WHERE d.deptno=20;
d.deptno là sai. Chỉ nên dùng deptno. Outer Join:
Có ba loại outer join:
- Left Outer Join: Nối hai bảng trả về kết quả của inner join, đồng thời các hàng không khớp của bảng bên trái gọi là LEFT OUTER JOIN
- Right Outer Join: Nối hai bảng trả về kết quả của inner join, đồng thời các hàng không khớp của bảng bên phải gọi là RIGHT OUTER JOIN.
- Full Outer Join: Nối hai bảng trả về kết quả của inner join, đồng thời các hàng không khớp của cả hai bảng gọi là FULL OUTER JOIN.
Xem lần lượt:
SELECT e.ename, s.grade FROM salgrade s LEFT OUTER JOIN employee e ON e.sal BETWEEN s.losal AND s.hisal; Output: ENAME DEPTNO DNAME ---------- ---------- -------------- SMITH 20 RESEARCH JONES 20 RESEARCH ALLEN 30 SALES WARD 30 SALES BLAKE 30 SALES.sal BETWEEN s.losal AND s.hisal; Output: ENAME DEPTNO DNAME ---------- ---------- -------------- SMITH 20 RESEARCH JONES 20 RESEARCH ALLEN 30 SALES WARD 30 SALES BLAKE 30 SALESSELECT e.ename, d.deptno, d.dname
FROM employee e RIGHT OUTER JOIN department d
ON e.deptno=d.deptno;
output:
ENAME DEPTNO DNAME
---------- ---------- --------------
SMITH 20 RESEARCH
ALLEN 30 SALES
WARD 30 SALES
JONES 20 RESEARCH
BLAKE 30 SALES
10 ACCOUNTINGSELECT e.ename, d.deptno, d.dname
FROM employee e FULL OUTER JOIN department d
ON e.deptno=d.deptno;
Output:
ENAME DEPTNO DNAME
---------- ---------- --------------
SMITH 20 RESEARCH
ALLEN 30 SALES
WARD 30 SALES
JONES 20 RESEARCH
BLAKE 30 SALES
10 ACCOUNTING
Bảng department có một hàng không khớp cho deptno 10, và không có hàng không khớp ở bảng employee. Tương tự, salgrade có một hàng không khớp cho grade 5.
Self-Join:
Có những tình huống bạn muốn nối một bảng với chính nó. Ví dụ, bảng employee chứa thông tin mọi nhân viên bao gồm cả quản lý (xem bảng employee ở trên). Nếu bạn cần tìm nhân viên và quản lý của họ, bạn sẽ nối bảng với chính nó. Self-Join thực hiện như sau:
SELECT e.ename as Employee, m.ename as Manager
FROM employee e, employee m
WHERE e.mgr=m.empno;
EMPLOYEE MANAGER
---------- ----------
ALLEN BLAKE
WARD BLAKE
Dùng truy vấn con để giải quyết truy vấn
Truy vấn con là truy vấn nằm trong một truy vấn. Truy vấn con hữu ích để chia nhỏ truy vấn lớn thành phần. Truy vấn con có thể lồng nhau và dùng trong các mệnh đề:
- WHERE
- FROM
- HAVING
Xét ví dụ; bạn cần tìm nhân viên có lương cao hơn một nhân viên khác, ở đây là James. Bạn sẽ làm thế nào? Truy vấn có thể tách thành:
- Tìm lương của James
- So sánh lương của James với tất cả nhân viên
Có thể giải bằng truy vấn con. Truy vấn con (bên trong) sẽ chạy một lần trước truy vấn chính (bên ngoài).
SELECT empno, ename FROM employee WHERE sal>(SELECT sal from employee where ename='JAMES');
Các loại truy vấn con:
-
Truy vấn con một hàng: Trả về duy nhất một hàng từ SELECT bên trong.
-
Truy vấn con nhiều hàng: Trả về hơn một hàng từ SELECT bên trong.
Điểm cần nhớ:
- Đặt truy vấn con trong ngoặc đơn.
- Đặt truy vấn con ở bên phải toán tử so sánh.
- Dùng toán tử một hàng (>, < , >= , <= , < >) với truy vấn con một hàng.
- Dùng toán tử nhiều hàng (IN, ANY, ALL) với truy vấn con nhiều hàng.
Truy vấn con một hàng:
Bạn được yêu cầu tìm tên nhân viên có chức danh giống empno 7521
SELECT ename, job
FROM employee
WHERE job=(SELECT job FROM employee WHERE empno=7521);
ENAME JOB
---------- ---------
ALLEN SALESMAN
WARD SALESMAN
Chọn mức lương tối đa của các phòng ban có lương tối đa lớn hơn hoặc bằng lương tối đa của phòng ban 20
SELECT deptno, max(sal)
FROM employee
GROUP BY deptno
HAVING max(sal)>=(SELECT max(sal) FROM employee WHERE deptno=20);
DEPTNO MAX(SAL)
---------- ----------
20 2975
Truy vấn con nhiều hàng:
Tìm nhân viên có lương bằng bất kỳ mức lương nào của nhân viên có job là Manager. Đây là truy vấn con nhiều hàng vì truy vấn con có thể trả về nhiều hàng.
SELECT ename, job, sal
FROM employee
WHERE sal IN (SELECT sal FROM employee WHERE job='MANAGER');
ENAME JOB SAL
---------- --------- ----------
JONES MANAGER 2975
BLAKE MANAGER 2850
Khi truy vấn con dùng trong mệnh đề FROM, nó hoạt động như một bảng tạm không tồn tại vật lý trên lưu trữ nhưng là một góc nhìn dữ liệu. Ví dụ:
SELECT e.ename, e.job, e.sal
FROM employee e, (SELECT deptno FROM department WHERE loc='DALLAS') d
WHERE e.deptno=d.deptno;
ENAME JOB SAL
---------- --------- ----------
SMITH CLERK 800
JONES MANAGER 2975
Dùng toán tử Tập hợp
Trong SQL, toán tử tập hợp dùng để kết hợp kết quả của nhiều truy vấn thành một kết quả. Nó dùng lý thuyết tập hợp trong toán học với các phép như UNION, MINUS, INTERSECT. Ở đây bạn sẽ thấy cách dùng các toán tử Tập hợp để tối ưu truy vấn. Trong hướng dẫn này sẽ bàn các toán tử sau.
Thông tin: Các truy vấn dùng toán tử Tập hợp gọi là câu lệnh tổng hợp (compound statements).
- UNION và UNION ALL
- INTERSECT
- EXCEPT (chuẩn SQL) và MINUS (đặc thù Oracle)
UNION
Xét hai quan hệ (bảng) R và S thì UNION chọn tất cả hàng từ R và tất cả hàng từ S đồng thời loại bỏ trùng lặp. Số hàng trả về tối đa là r+s, với r là số hàng của R và s là số hàng của S.
Chọn tất cả tên phòng ban bao gồm cả tên phòng ban của nhân viên được tuyển trước 23-OCT-1999
SELECT dname
FROM department
UNION
SELECT dname
FROM department, employee
WHERE department.deptno=employee.deptno AND employee.hiredate<to_date('23-OCT-1999');
DNAME
--------------
ACCOUNTING
OPERATIONS
RESEARCH
SALES
Điểm cần nhớ về UNION:
- Số lượng cột và kiểu dữ liệu của các cột được chọn phải giống hệt nhau trong tất cả các SELECT của truy vấn.
- Tên cột không cần giống nhau.
- Đầu ra được sắp tăng dần theo cột đầu tiên của mệnh đề SELECT.
- Giá trị NULL không bị bỏ qua khi kiểm tra trùng lặp.
UNION ALL kết hợp kết quả từ một hay nhiều truy vấn và KHÔNG loại bỏ trùng lặp, do đó không dùng từ khóa DISTINCT. Giả sử có bảng emp chứa nhân viên từ năm 2000. Lấy tất cả số, tên và job từ bảng emp và employee:
SELECT empno, ename, job
FROM employee
UNION ALL
SELECT empno, ename, job
FROM emp;
EMPNO ENAME JOB
---------- ---------- ---------
7369 SMITH CLERK
7499 ALLEN SALESMAN
7521 WARD SALESMAN
7566 JONES MANAGER
7698 BLAKE MANAGER
7369 SMITH CLERK
7499 ALLEN SALESMAN
7521 WARD SALESMAN
7566 JONES MANAGER
7654 MARTIN SALESMAN
7698 BLAKE MANAGER
EMPNO ENAME JOB
---------- ---------- ---------
7782 CLARK MANAGER
7788 SCOTT ANALYST
7839 KING PRESIDENT
7844 TURNER SALESMAN
7876 ADAMS CLERK
7900 JAMES CLERK
INTERSECT
Phép giao tuân theo lý thuyết tập hợp, trả về các giá trị chung của hai tập. Xét hai quan hệ R và S, INTERSECT trả về tập tất cả bộ chung của cả R và S.
SELECT empno, ename, job
FROM employee
INTERSECT
SELECT empno, ename, job
FROM emp;
EMPNO ENAME JOB
---------- ---------- ---------
7369 SMITH CLERK
7499 ALLEN SALESMAN
7521 WARD SALESMAN
7566 JONES MANAGER
7698 BLAKE MANAGER
Điểm cần nhớ về INTERSECT:
- Số lượng cột và kiểu dữ liệu của các cột được chọn phải giống hệt nhau trong tất cả các SELECT của truy vấn.
- Tên cột không cần giống nhau.
- INTERSECT không bỏ qua giá trị NULL
EXCEPT và MINUS:
EXCEPT (dùng trong SQL Server) và MINUS (đặc thù Oracle) có chức năng như nhau. Mục đích là chọn tất cả các hàng phân biệt được chọn bởi truy vấn đầu tiên nhưng không có trong truy vấn thứ hai. Để hiểu, xét bảng sau:

Giả sử, bạn cần tìm sản phẩm có số lượng từ 1 đến 100 nhưng không có số lượng 50-75. Bạn sẽ dùng EXCEPT nếu dùng SQL Server và MINUS nếu dùng Oracle.
SELECT prod_name, qty FROM products WHERE qty BETWEEN 1 AND 100 EXCEPT SELECT prod_name, qty FROM products WHERE qty BETWEEN 50 AND 75;
Với Oracle:
SELECT prod_name, qty
FROM products
WHERE qty BETWEEN 1 AND 100
MINUS
SELECT prod_name, qty
FROM products
WHERE qty BETWEEN 50 AND 75;
PROD_NAME QTY
------------- ----------
COLGATE 1
SENSODYNE 100
SENSODYNE TOOTHBRUSH 30
Điểm cần nhớ về EXCEPT/MINUS:
- Số lượng cột và kiểu dữ liệu của các cột được chọn phải giống hệt nhau trong tất cả các SELECT của truy vấn.
- Tên cột không cần giống nhau.
- Tất cả cột trong mệnh đề WHERE phải có trong mệnh đề SELECT thì toán tử MINUS mới hoạt động.
Chúc mừng!
Bạn đã đến cuối hướng dẫn. Trong hướng dẫn này, bạn đã học một lượng kiến thức SQL đáng kể giúp bạn làm chủ SQL trong hành trình khoa học dữ liệu. SQL dùng để tạo báo cáo từ cơ sở dữ liệu. Bạn đã học nền tảng về cơ sở dữ liệu và SQL, các kiểu dữ liệu phổ biến, các hàm giúp định dạng báo cáo, tổng hợp kết quả tạo bản tóm tắt và cả cách lấy dữ liệu từ các bảng khác nhau theo yêu cầu! Hướng dẫn này được thiết kế riêng cho người học khoa học dữ liệu, không chỉ giúp với cơ sở dữ liệu quan hệ mà còn hỗ trợ tiếp cận suôn sẻ cơ sở dữ liệu NoSQL và vận dụng kỹ năng SQL trong học tập Big Data.
Nếu bạn muốn học thêm về SQL, hãy học khóa miễn phí Intro to SQL for Data Science của DataCamp.