首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server APPLY 運算子深度解析:CROSS APPLY 與 OUTER APPLY 實戰

     編輯:關於SqlServer

APPLY 運算子允許對左側資料表的每一列,呼叫右側的資料表值函數,並將結果合併輸出。它分為 CROSS APPLY(僅保留有相符結果的左列)與 OUTER APPLY(保留所有左列,無相符則以 NULL 填充),功能類似 INNER JOIN 與 LEFT JOIN,但支援逐列動態運算。

範例資料準備

CREATE TABLE test4 (id INT IDENTITY(1,1), name VARCHAR(100));
CREATE TABLE test4Score (test4id INT, score INT);

INSERT INTO test4(name) VALUES ('LeeWhoeeUniversity'), ('LeeWhoee'), ('DePaul');
INSERT INTO test4Score(test4id, score) VALUES
(1,100),(1,90),(1,90),(1,80),
(2,90),(2,82),(2,10);

test4

idname
1LeeWhoeeUniversity
2LeeWhoee
3DePaul

test4Score

test4idscore
1100
190
190
180
290
282
210

CROSS APPLY:取得每個 name 前兩高分數

SELECT *
FROM test4 a
CROSS APPLY (
    SELECT TOP 2 * FROM test4Score WHERE test4id = a.id ORDER BY score DESC
) b;

運作邏輯:左輸入為 test4 三列;對每列,右輸入以該列 id 為條件查詢 test4Score 前兩高分。DePaul (id=3) 無對應分數,故被過濾。

結果:

idnametest4idscore
1LeeWhoeeUniversity1100
1LeeWhoeeUniversity190
2LeeWhoee290
2LeeWhoee282

OUTER APPLY:保留無分數的學生

SELECT *
FROM test4 a
OUTER APPLY (
    SELECT TOP 2 * FROM test4Score WHERE test4id = a.id ORDER BY score DESC
) b;

結果:多出 DePaul 一列,右側欄位為 NULL。

idnametest4idscore
1LeeWhoeeUniversity1100
1LeeWhoeeUniversity190
2LeeWhoee290
2LeeWhoee282
3DePaulNULLNULL

替代寫法:ROW_NUMBER() 分區排序

SELECT b.name, a.score
FROM (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY test4id ORDER BY score DESC) AS rn
    FROM test4Score
) a
INNER JOIN test4 b ON b.id = a.test4id
WHERE a.rn < 3;

此法利用視窗函數分區排序,效能亦佳,適用於不支援 APPLY 的舊版本。

舊式子查詢寫法(需身分欄位)

若 test4Score 有 id 身分欄,可用相關子查詢:

SELECT a.name, b.score
FROM test4 a
INNER JOIN test4Score b ON a.id = b.test4id
WHERE b.id IN (
    SELECT TOP 2 id FROM test4Score WHERE test4id = b.test4id ORDER BY score DESC
);
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved