DISTINCT
和
ORDER BY
是兩個常用Oracle SQL文法的SQL子句。其中,
DISTINCT
用於消除查詢結果中的重複記錄,
ORDER BY
用於對查詢結果進行排序。當這兩個子句結合使用時,需要注意它們的文法和執行順序。本文將詳細介紹如何在Oracle SQL文法使用
DISTINCT
和
ORDER BY
,並通過樣本協助您更好地理解和應用。
基本文法
SELECT DISTINCT column1, column2, ...
FROM table_name
WHERE condition
ORDER BY column1 [ASC|DESC], column2 [ASC|DESC], ...;
-
SELECT DISTINCT:選擇唯一不同的記錄,消除重複行。
-
FROM:指定查詢的資料表。
-
WHERE:可選,指定查詢條件。
-
ORDER BY:對結果集進行排序,可以指定一個或多個列,並選擇升序 (
ASC) 或降序 (DESC)。
工作原理
在SQL查詢中,
DISTINCT
會在
ORDER BY
之前執行,即先篩選出唯一的記錄,然後再對這些唯一記錄進行排序。
使用樣本
假設有一個名為
employees
的表,結構如下:
CREATE TABLE employees (
employee_id INT PRIMARY KEY , -- 員工唯一標識
first_name VARCHAR(50) NOT NULL, -- 員工名字
last_name VARCHAR(50) NOT NULL, -- 員工姓氏
department VARCHAR(50), -- 部門編號
salary DECIMAL(10, 2) CHECK (salary > 0) -- 薪資
INSERT INTO employees VALUES (1, 'John', 'Doe', 'Sales', 5000);
INSERT INTO employees VALUES (2, 'Jane', 'Smith', 'Marketing', 6000);
INSERT INTO employees VALUES (3, 'John', 'Doe', 'Sales', 5000);
INSERT INTO employees VALUES (4, 'Alice', 'Johnson', 'IT', 7000);
INSERT INTO employees VALUES (5, 'Bob', 'Brown', 'Sales', 5000);
-
選擇唯一的部門並按名稱排序。
SELECT DISTINCT DEPARTMENT FROM employees ORDER BY DEPARTMENT ASC;返回結果如下:
department ------------ Marketing Sales (3 rows) -
選擇唯一的工資,並按工資降序排序。
SELECT DISTINCT SALARY FROM employees ORDER BY SALARY DESC;返回結果如下:
salary --------- 7000.00 6000.00 5000.00 (3 rows) -
選擇唯一的姓名組合并排序。
SELECT DISTINCT FIRST_NAME, LAST_NAME FROM employees ORDER BY FIRST_NAME ASC, LAST_NAME ASC;返回結果如下:
說明即使有多條記錄的
FIRST_NAME和LAST_NAME相同,DISTINCT只會返回一條唯一的組合。first_name | last_name ------------+----------- Alice | Johnson Bob | Brown Jane | Smith John | Doe (4 rows)
注意事項
-
ORDER BY中的列
在使用
ORDER BY時,所指定的列必須出現在SELECT子句中。如果在ORDER BY中引用不在SELECT中的列, PolarDB 將報錯。錯誤樣本:
SELECT DISTINCT FIRST_NAME FROM employees ORDER BY LAST_NAME ASC;報錯如下:
ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list然而,由於Oracle的相容性原因,可以通過啟用參數polar_enable_distinct_orderby_new_column來合法引用不在SELECT語句中的列。該用法使用步驟如下:
-
啟用polar_enable_distinct_orderby_new_column參數。
說明PolarDB PostgreSQL版 Oracle文法相容 2.0 在核心小版本2.0.14.26.0新增
polar_enable_distinct_orderby_new_column參數。若叢集的核心小版本低於該版本且需要合法引用不在SELECT語句中的列,請將核心小版本升級到2.0.14.26.0或以上版本。查詢和升級核心小版本,請參見 版本管理 。 -
在
ORDER BY中引用不在SELECT中的列。 -
查詢末尾添加
FETCH FIRST X rows ONLY或LIMIT欄位。SELECT DISTINCT FIRST_NAME FROM employees ORDER BY LAST_NAME ASC FETCH FIRST 2 rows ONLY;
-
-
使用別名
支援為
SELECT中的列指定別名,並在ORDER BY中使用這些別名。SELECT DISTINCT FIRST_NAME AS FN FROM employees ORDER BY FN ASC; -
ORDER BY列的位置
支援使用列的位置來排序,例如
ORDER BY 1表示按SELECT中第一個列排序。SELECT DISTINCT FIRST_NAME, LAST_NAME FROM employees ORDER BY 1 ASC;
進階用法
-
結合
WHERE子句在使用
DISTINCT和ORDER BY時,可以添加WHERE子句以篩選特定記錄。樣本:
SELECT DISTINCT DEPARTMENT FROM employees WHERE SALARY > 5000 ORDER BY DEPARTMENT ASC;返回結果如下:
department ------------ Marketing (2 rows) -
使用子查詢
在某些複雜的查詢情境中,可以使用子查詢結合
DISTINCT和ORDER BY。樣本:
假設需要先找出工資最高的每個部門,然後按部門名稱排序:
SELECT DEPARTMENT, MAX(SALARY) AS MAX_SALARY FROM employees GROUP BY DEPARTMENT ORDER BY DEPARTMENT ASC;返回結果如下:
department | max_salary ------------+------------ IT | 7000.00 Marketing | 6000.00 Sales | 5000.00 (3 rows) -
結合視窗函數
當需要在
DISTINCT和ORDER BY的基礎上進行更複雜的資料分析時,可以結合使用視窗函數。樣本:
選出每個部門中工資最高的員工,並按薪資降序排列。
SELECT DISTINCT DEPARTMENT, FIRST_NAME, LAST_NAME, SALARY FROM ( SELECT DEPARTMENT, FIRST_NAME, LAST_NAME, SALARY, ROW_NUMBER() OVER (PARTITION BY DEPARTMENT ORDER BY SALARY DESC) AS rn FROM employees WHERE rn = 1 ORDER BY SALARY DESC;返回結果如下:
department | first_name | last_name | salary ------------+------------+-----------+-------- IT | Alice | Johnson | 7000 Marketing | Jane | Smith | 6000 Sales | John | Doe | 5000 (3 rows)
常見錯誤與調試
使用不在WHERE中的列進行排序
混淆DISTINCT的作用範圍
效能最佳化
在處理巨量資料集時,使用
DISTINCT
和
ORDER BY
可能會對查詢效能產生影響。以下是一些最佳化建議:
-
索引最佳化:為
WHERE、DISTINCT和ORDER BY使用的列建立適當的索引,加快查詢速度。 -
減少返回的列數:只選擇必要的列,避免不必要的資料處理。
-
使用分區:對大表進行分區,可以提高查詢效率。
-
查詢計劃分析:使用
EXPLAIN PLAN分析查詢執行計畫,發現潛在的效能瓶頸。
樣本:
使用索引最佳化。
-- 建立索引以最佳化 DEPARTMENT 列的查詢
CREATE INDEX idx_employees_department ON employees(DEPARTMENT);
總結
DISTINCT
和
ORDER BY
是
PolarDB
SQL中功能強大的工具,用於消除重複記錄和對結果集進行排序。瞭解其工作原理、正確文法及常見使用情境,有助於您編寫高效且準確的查詢。在實際應用中,根據具體需求合理組合這兩個子句,並結合其他SQL功能,可以實現複雜的資料處理與分析任務。