【SQL語法進階】SQL Server與Oracle語法差異與實戰範例

資料庫

在實際應用中,SQL 查詢往往會涉及到更為複雜的場景,如多表聯接、窗口函數、複雜的子查詢和資料分組等。本文將介紹一些進階的 SQL 查詢語法,幫助你在 SQL Server 和 Oracle 中處理更複雜的數據操作。

1. 多表聯接(JOIN)

假設有三個表格:EmployeesDepartmentsSalaries,我們需要查詢每個部門中的員工及其薪水。

表格結構:

  • Employees 表:EmployeeID, Name, DepartmentID
  • Departments 表:DepartmentID, DepartmentName
  • Salaries 表:EmployeeID, Salary

例子:列出相關資訊

列出所有員工的姓名、部門名稱以及薪水,並按薪水降序排列。

SQL 查詢:

SELECT e.Name, d.DepartmentName, s.Salary
FROM Employees e
INNER JOIN Departments d ON e.DepartmentID = d.DepartmentID
INNER JOIN Salaries s ON e.EmployeeID = s.EmployeeID
ORDER BY s.Salary DESC;

這個查詢首先將 Employees 表與 Departments 表、Salaries 表進行內聯接(INNER JOIN),然後根據薪水對結果進行排序。

2. 窗口函數(Window Functions)

窗口函數允許你在查詢中對某一個分組或排序進行操作,而不會影響查詢的結果集。常見的窗口函數有 ROW_NUMBER()RANK()DENSE_RANK() 等。

例子:查詢員工薪水排名

假設我們有一個 Salaries 表,包含員工的 EmployeeIDSalary,我們想要查詢員工的薪水排名。

SELECT EmployeeID, Salary,
ROW_NUMBER() OVER (ORDER BY Salary DESC) AS SalaryRank
FROM Salaries;
  • ROW_NUMBER() 函數為每行數據分配一個唯一的排名,並且根據 Salary 降序排列。這樣,薪水最高的員工會獲得排名 1。

注意:

窗口函數在 SQL Server 和 Oracle 中的語法是相同的。

3. 使用子查詢進行條件篩選

有時我們需要使用子查詢來篩選數據,特別是在 WHERE 子句中。以下是一個例子,假設我們有兩個表格:EmployeesSalaries,並希望查詢薪水高於所有員工薪水平均值的員工。

SQL 查詢:

SELECT e.EmployeeID, e.Name, s.Salary
FROM Employees e
INNER JOIN Salaries s ON e.EmployeeID = s.EmployeeID
WHERE s.Salary > (
SELECT AVG(Salary)
FROM Salaries
);

這個查詢首先計算出所有員工的平均薪水,然後選擇薪水高於平均值的員工。

4. 使用CASE語句進行條件處理

CASE 語句用於在 SQL 查詢中進行條件邏輯運算。它可以在 SELECTUPDATEORDER BY 等地方使用。

例子:根據員工薪水給予薪資等級

假設我們想要根據薪水給每個員工分配一個等級,薪水高於 80000 的員工為 “High”,介於 50000 到 80000 之間的員工為 “Medium”,低於 50000 的員工為 “Low”。

SELECT EmployeeID, Name, Salary,
CASE
WHEN Salary > 80000 THEN 'High'
WHEN Salary BETWEEN 50000 AND 80000 THEN 'Medium'
ELSE 'Low'
END AS SalaryLevel
FROM Employees;

這個查詢使用 CASE 條件語句根據每位員工的薪水給出對應的薪資等級。

5. 使用GROUP BY和HAVING進行分組和過濾

當你需要對數據進行分組並根據某些條件篩選結果時,可以使用 GROUP BYHAVINGGROUP BY 用來將數據分組,HAVING 用於對分組後的數據進行過濾。

例子:查詢每個部門的員工數量,並過濾出員工數量大於 5 的部門

SELECT d.DepartmentName, COUNT(e.EmployeeID) AS EmployeeCount
FROM Employees e
INNER JOIN Departments d ON e.DepartmentID = d.DepartmentID
GROUP BY d.DepartmentName
HAVING COUNT(e.EmployeeID) > 5;

這個查詢首先將員工按部門進行分組,然後過濾出員工數量大於 5 的部門。

6. 複雜的子查詢與EXISTS

EXISTS 用於檢查子查詢是否返回結果。它通常用於條件過濾,特別是在處理多表聯接時。

例子:查詢有薪水的員工(存在薪水記錄)

SELECT e.EmployeeID, e.Name
FROM Employees e
WHERE EXISTS (
SELECT 1
FROM Salaries s
WHERE s.EmployeeID = e.EmployeeID
);

這個查詢使用 EXISTS 子查詢來過濾出有對應薪水記錄的員工。

7. 使用UNION合併結果集

UNION 用於將兩個或多個查詢的結果合併為一個結果集,並去除重複的行。如果你希望保留重複的行,可以使用 UNION ALL

例子:從兩個不同的表中查詢員工姓名和部門名稱

SELECT Name AS EmployeeName, 'Employee' AS Source
FROM Employees
UNION
SELECT DepartmentName AS EmployeeName, 'Department' AS Source
FROM Departments;

這個查詢將來自 EmployeesDepartments 表的數據合併成一個結果集,並添加一個名為 Source 的列來標示數據來源。

結語

以上介紹一些常見的複雜查詢語法,這些查詢不僅涵蓋了多表聯接、窗口函數、子查詢等進階操作,還包括了如何使用 CASE 進行條件邏輯處理、如何使用 GROUP BYHAVING 進行數據分組等。希望能夠在 SQL 查詢中靈活應對各種需求。

發佈留言