Thứ Tư, 5 tháng 8, 2020

SQL cơ bản - Bài 4: Mệnh đề ORDER BY

Trong bài viết này, chúng ta sẽ xem làm thế nào bạn có thể ảnh hưởng đến thứ tự của dữ liệu được trả về bởi các truy vấn.

  • Thiết lập môi trường
  • Giới thiệu
  • Xác định các Cột: Biểu thức, Vị trí và Bí danh Cột
  • Thứ tự tăng dần (ASC) và giảm dần (DESC)
  • Xử lý NULL: NULLS FIRST và NULLS LAST

Thiết lập môi trường

Bạn có thể thực hiện tất cả các truy vấn trực tuyến miễn phí bằng SQL Fiddle .
Các ví dụ trong bài viết này yêu cầu phải có các bảng sau đây.
--DROP TABLE employees PURGE;
--DROP TABLE departments PURGE;

CREATE TABLE departments (
  department_id   NUMBER(2) CONSTRAINT departments_pk PRIMARY KEY,
  department_name VARCHAR2(14),
  location        VARCHAR2(13)
);

INSERT INTO departments VALUES (10,'ACCOUNTING','NEW YORK');
INSERT INTO departments VALUES (20,'RESEARCH','DALLAS');
INSERT INTO departments VALUES (30,'SALES','CHICAGO');
INSERT INTO departments VALUES (40,'OPERATIONS','BOSTON');
COMMIT;


CREATE TABLE employees (
  employee_id   NUMBER(4) CONSTRAINT employees_pk PRIMARY KEY,
  employee_name VARCHAR2(10),
  job           VARCHAR2(9),
  manager_id    NUMBER(4),
  hiredate      DATE,
  salary        NUMBER(7,2),
  commission    NUMBER(7,2),
  department_id NUMBER(2) CONSTRAINT emp_department_id_fk REFERENCES departments(department_id)
);

INSERT INTO employees VALUES (7369,'SMITH','CLERK',7902,to_date('17-12-1980','dd-mm-yyyy'),800,NULL,20);
INSERT INTO employees VALUES (7499,'ALLEN','SALESMAN',7698,to_date('20-2-1981','dd-mm-yyyy'),1600,300,30);
INSERT INTO employees VALUES (7521,'WARD','SALESMAN',7698,to_date('22-2-1981','dd-mm-yyyy'),1250,500,30);
INSERT INTO employees VALUES (7566,'JONES','MANAGER',7839,to_date('2-4-1981','dd-mm-yyyy'),2975,NULL,20);
INSERT INTO employees VALUES (7654,'MARTIN','SALESMAN',7698,to_date('28-9-1981','dd-mm-yyyy'),1250,1400,30);
INSERT INTO employees VALUES (7698,'BLAKE','MANAGER',7839,to_date('1-5-1981','dd-mm-yyyy'),2850,NULL,30);
INSERT INTO employees VALUES (7782,'CLARK','MANAGER',7839,to_date('9-6-1981','dd-mm-yyyy'),2450,NULL,10);
INSERT INTO employees VALUES (7788,'SCOTT','ANALYST',7566,to_date('13-JUL-87','dd-mm-rr')-85,3000,NULL,20);
INSERT INTO employees VALUES (7839,'KING','PRESIDENT',NULL,to_date('17-11-1981','dd-mm-yyyy'),5000,NULL,10);
INSERT INTO employees VALUES (7844,'TURNER','SALESMAN',7698,to_date('8-9-1981','dd-mm-yyyy'),1500,0,30);
INSERT INTO employees VALUES (7876,'ADAMS','CLERK',7788,to_date('13-JUL-87', 'dd-mm-rr')-51,1100,NULL,20);
INSERT INTO employees VALUES (7900,'JAMES','CLERK',7698,to_date('3-12-1981','dd-mm-yyyy'),950,NULL,30);
INSERT INTO employees VALUES (7902,'FORD','ANALYST',7566,to_date('3-12-1981','dd-mm-yyyy'),3000,NULL,20);
INSERT INTO employees VALUES (7934,'MILLER','CLERK',7782,to_date('23-1-1982','dd-mm-yyyy'),1300,NULL,10);
COMMIT;
Các bảng này là một biến thể của các bảng EMP và DEPT từ lược đồ SCOTT. Bạn sẽ thấy rất nhiều ví dụ của Oracle trên internet bằng cách sử dụng các bảng từ lược đồ SCOTT. Bạn có thể tìm thấy các định nghĩa bảng gốc trong tập lệnh "$ORACLE_HOME/rdbms/admin/utlsampl.sql".

Giới thiệu

Nơi tốt nhất để bắt đầu, là với trích dẫn này từ tài liệu ( ở đây ).
"Sử dụng mệnh đề ORDER BY để sắp xếp các hàng được trả về bởi câu lệnh. Nếu không có order_by_clause, không có đảm bảo nào tồn tại rằng cùng một truy vấn được thực hiện nhiều lần sẽ truy xuất các hàng theo cùng một thứ tự."
Khi bạn bắt đầu học SQL, rất dễ quên điều này và bắt đầu tin rằng có một mẫu có thể dự đoán được với đầu ra của dữ liệu. Có một vài lý do điều này có thể xảy ra.
  • Nếu bạn đang sử dụng một lượng nhỏ dữ liệu thử nghiệm, tất cả các row có thể được tải vào một block, do đó, các row có thể được trả về theo cách có thể dự đoán được. Khi bạn làm việc vỡi liệu hệ thống production, giả định của bạn có thể được chứng minh là sai.
  • Có thể có một loại ngầm định được thực hiện bởi một hoặc nhiều thao tác trong truy vấn của bạn, làm cho đầu ra có thể dự đoán được, nhưng đó chỉ có thể là phiên bản cụ thể và có thể là phiên bản vá bạn đang chạy. Oracle có thể thay đổi thuật toán tại bất kỳ thời điểm nào trong tương lai, điều này có thể "phá vỡ" ứng dụng của bạn. Oracle đã nói với bạn cách bảo vệ bản thân trong tuyên bố trên.
Các tài liệu sử dụng mô tả văn bản sau đây cho các mệnh đề ORDER BY.
ORDER [ SIBLINGS ] BY
{ expr | position | c_alias }
[ ASC | DESC ]
[ NULLS FIRST | NULLS LAST ]
  [, { expr | position | c_alias }
     [ ASC | DESC ]
     [ NULLS FIRST | NULLS LAST ]
  ]...
Các phần sau đây sẽ trình bày một số tùy chọn này.

Xác định các Cột: Biểu thức, Vị trí và Bí danh Cột

Có ba cách chính để xác định các cột có trong hoạt động sắp xếp. Có lẽ biểu thức phổ biến nhất là chỉ định một hoặc nhiều cột trong danh sách được phân tách bằng dấu phẩy. Trong ví dụ sau, các kết quả được sắp xếp theo các cột SALARY và COMMISSION.
SELECT e.salary, e.commission, e.employee_name
FROM   employees e
WHERE  department_id = 30
ORDER BY e.salary, e.commission;

    SALARY COMMISSION EMPLOYEE_N
---------- ---------- ----------
       950            JAMES
      1250        500 WARD
      1250       1400 MARTIN
      1500          0 TURNER
      1600        300 ALLEN
      2850            BLAKE

6 rows selected.

SQL>
Trong số những thứ khác, biểu thức có thể bao gồm nhiều cột được kết hợp với nhau. Trong ví dụ sau, các kết quả được sắp xếp theo tổng của các cột SALARY và COMMISSION. Các hàm NVL chuyển đổi bất kỳ giá trị NULL trong cột COMMISSION bằng không, để làm cho kết quả của việc bổ sung rõ ràng hơn.
SELECT e.salary, e.commission, e.employee_name
FROM   employees e
WHERE  department_id = 30
ORDER BY e.salary + NVL(e.commission,0);

    SALARY COMMISSION EMPLOYEE_N
---------- ---------- ----------
       950            JAMES
      1500          0 TURNER
      1250        500 WARD
      1600        300 ALLEN
      1250       1400 MARTIN
      2850            BLAKE

6 rows selected.

SQL>
Các cột có thể được tham chiếu bởi vị trí cột của chúng. Hãy nhớ rằng, nếu bạn thay đổi SELECT, bạn cũng sẽ phải sửa đổi mệnh đề ORDER BY.
SELECT e.salary, e.commission, e.employee_name
FROM   employees e
WHERE  department_id = 30
ORDER BY 1;

    SALARY COMMISSION EMPLOYEE_N
---------- ---------- ----------
       950            JAMES
      1250        500 WARD
      1250       1400 MARTIN
      1500          0 TURNER
      1600        300 ALLEN
      2850            BLAKE

6 rows selected.

SQL>
Các cột cũng có thể được tham chiếu bằng bí danh cột của chúng. Trong ví dụ sau, cột SALARY được đặt bí danh là SAL, được sử dụng trong mệnh đề ORDER BY.
SELECT e.salary AS sal, e.commission, e.employee_name
FROM   employees e
WHERE  department_id = 30
ORDER BY sal;

       SAL COMMISSION EMPLOYEE_N
---------- ---------- ----------
       950            JAMES
      1250        500 WARD
      1250       1400 MARTIN
      1500          0 TURNER
      1600        300 ALLEN
      2850            BLAKE

6 rows selected.

SQL>

Thứ tự tăng dần (ASC) và giảm dần (DESC)

Thứ tự mặc định là tăng dần, vì vậy các câu lệnh sau là tương đương về chức năng.
-- Tăng đần (ASC) là mặc định.
SELECT e.salary AS sal, e.commission, e.employee_name
FROM   employees e
WHERE  department_id = 30
ORDER BY e.salary;

       SAL COMMISSION EMPLOYEE_N
---------- ---------- ----------
       950            JAMES
      1250        500 WARD
      1250       1400 MARTIN
      1500          0 TURNER
      1600        300 ALLEN
      2850            BLAKE

6 rows selected.

SQL>

-- Tường minh ASC.
SELECT e.salary AS sal, e.commission, e.employee_name
FROM   employees e
WHERE  department_id = 30
ORDER BY e.salary ASC;

       SAL COMMISSION EMPLOYEE_N
---------- ---------- ----------
       950            JAMES
      1250        500 WARD
      1250       1400 MARTIN
      1500          0 TURNER
      1600        300 ALLEN
      2850            BLAKE

6 rows selected.

SQL>
Để chuyển sang giảm dần, sử dụng từ khóa DESC.
SELECT e.salary AS sal, e.commission, e.employee_name
FROM   employees e
WHERE  department_id = 30
ORDER BY e.salary DESC;

       SAL COMMISSION EMPLOYEE_N
---------- ---------- ----------
      2850            BLAKE
      1600        300 ALLEN
      1500          0 TURNER
      1250        500 WARD
      1250       1400 MARTIN
       950            JAMES

6 rows selected.

SQL>
Mỗi cột trong mệnh đề ORDER BY có thể có một thứ tự khác nhau.
SELECT e.salary, e.commission, e.employee_name
FROM   employees e
WHERE  department_id = 30
ORDER BY e.salary ASC, e.commission DESC;

    SALARY COMMISSION EMPLOYEE_N
---------- ---------- ----------
       950            JAMES
      1250       1400 MARTIN
      1250        500 WARD
      1500          0 TURNER
      1600        300 ALLEN
      2850            BLAKE

6 rows selected.

SQL>

Xử lý NULL: NULLS FIRST và NULLS LAST

Một thứ tự tăng dần giả định NULLS LASTBạn có thể chỉ định nó một cách rõ ràng nếu bạn muốn.
SELECT e.commission, e.employee_name
FROM   employees e
WHERE  department_id = 30
ORDER BY e.commission ASC;

COMMISSION EMPLOYEE_N
---------- ----------
         0 TURNER
       300 ALLEN
       500 WARD
      1400 MARTIN
           JAMES
           BLAKE

6 rows selected.

SQL>
Mặc định có thể được thay đổi bằng cách chỉ định NULLS FIRST.
SELECT e.commission, e.employee_name
FROM   employees e
WHERE  department_id = 30
ORDER BY e.commission ASC NULLS FIRST;

COMMISSION EMPLOYEE_N
---------- ----------
           JAMES
           BLAKE
         0 TURNER
       300 ALLEN
       500 WARD
      1400 MARTIN

6 rows selected.

SQL>
Một thứ tự giảm dần giả định NULLS FIRSTBạn có thể chỉ định nó một cách rõ ràng nếu bạn muốn.
SELECT e.commission, e.employee_name
FROM   employees e
WHERE  department_id = 30
ORDER BY e.commission DESC;

COMMISSION EMPLOYEE_N
---------- ----------
           BLAKE
           JAMES
      1400 MARTIN
       500 WARD
       300 ALLEN
         0 TURNER

6 rows selected.

SQL>
Mặc định có thể được thay đổi bằng cách chỉ định NULLS LAST.
SELECT e.commission, e.employee_name
FROM   employees e
WHERE  department_id = 30
ORDER BY e.commission DESC NULLS LAST;

COMMISSION EMPLOYEE_N
---------- ----------
      1400 MARTIN
       500 WARD
       300 ALLEN
         0 TURNER
           JAMES
           BLAKE

6 rows selected.

SQL>
Mỗi cột trong mệnh đề ORDER BY có thể có cách xử lý NULL khác nhau.

SELECT e.salary, e.commission, e.employee_name
FROM   employees e
WHERE  department_id = 30
ORDER BY e.salary ASC NULLS FIRST, e.commission DESC NULLS LAST;

    SALARY COMMISSION EMPLOYEE_N
---------- ---------- ----------
       950            JAMES
      1250       1400 MARTIN
      1250        500 WARD
      1500          0 TURNER
      1600        300 ALLEN
      2850            BLAKE

6 rows selected.

SQL>
------
@ Trần Văn Bình - Founder of "Oracle DBA Việt Nam" #OracleTutorial #OracleDBA #OracleDatabaseAdministration #học oracle database #oca #ocp #oce #ocm

ĐỌC NHIỀU

Trần Văn Bình - Oracle Database Master