Ranking函數
1 CREATETABLE[Test]下面是四個排序函數統一的示例和結果,可以做一比較。下面的小節來會逐一據此描述每個函數。
2 (
3 [StudentID][bigint]NOTNULL,
4 [ClassID][bigint]NOTNULL,
5 [TestScore][decimal](4, 1) NOTNULL
6 ) ON[PRIMARY]
7 GO
8
9 INSERTINTO[Test]
10 VALUES (100001,100,90),
11 (100002,100,85.5),
12 (100003,100,80),
13 (100004,100,80),
14 (100005,100,74),
15 (101001,101,94),
16 (101002,101,85.5),
17 (101003,101,85.5)
18 GO
19
1 SELECT*,
2 ROW_NUMBER() OVER (ORDERBY TestScore DESC) as RN,
3 RANK() OVER (ORDERBY TestScore DESC) as R,
4 DENSE_RANK() OVER (ORDERBY TestScore DESC) as DR,
5 NTILE(3) OVER (ORDERBY TestScore DESC) as N3
6 FROM[TEST]
7 GO
8
1 SELECT*, ROW_NUMBER() OVER (ORDERBY TestScore DESC) as RNRANK 排序函數。必須配合over函數,且排序字段值相同的行號一樣,同時隱藏行號會占位。 語法: RANK() OVER ([<partition_by_clause>] <order_by_clause>) 還可以利用partition進行分組排序,例如對每個班級分別按成績排序:
2 FROM[TEST]
3 WHERE RN BETWEEN6AND10
4
從第一個結果集中可以看到,DENSE_RANK得到的行號是3,3,3,4,4,5,而RANK函數得到的3,3,3,6,6,8。 NTILE 分區排序函數。NTILE函數需要一個參數N,這個參數支持bigint。這個函數將結果集等分成N個區,並按排序字段將已排序的記錄依次輪流放入各個區內。最後每個區內會從1開始編號,NTILE函數返回這個編號。 語法: NTILE (integer_expression) OVER ([<partition_by_clause>]< order_by_clause>)
這個函數可以用來按權值均分記錄。 從第一個結果集可以看到被分成了3個區,因為8條記錄不能被平分,所以第3個區只有2條記錄。排序的記錄被依次按第1->2->3->1區的順序分配,最終函數的返回是每個區內記錄的序號。
1 SELECT*, RANK() OVER (PARTITION BY ClassID ORDERBY TestScore DESC) as R
2 FROM[Test]
3
1 ;WITH Test_RN
2 AS
3 (
4 SELECT StudentID, ClassID, TestScore,RANK() OVER (PARTITION BY ClassID ORDERBY TestScore DESC) as RN
5 From Test
6 )
7 Select*FROM Test_RN WHERE RN=1
8
1 CREATETABLE[Dept]我們需要獲取“總公司”下所有部門的信息:
2 (
3 [DeptID][bigint]NOTNULL,
4 [DeptName][nvarchar](50) NOTNULL,
5 [ParentDeptID][bigint]NOTNULL
6 ) ON[PRIMARY]
7 GO
8
9 INSERTINTO[SSIP-SSO].[dbo].[Dept]
10 VALUES
11 (1, '集團', 0),
12 (2, '總公司', 1),
13 (3, '技術部', 2),
14 (4, '開發組', 3),
15 (5, '測試部', 3),
16 (6, '財務部', 2),
17 (7, '分公司', 1),
18 (8, '工程部', 7),
19 (9, '設備組', 8),
20 (10, '客服部', 7)
21 GO
22
1 ;WITH Dept_Head
2 AS
3 (
4 SELECT DeptID, DeptName, ParentDeptID
5 FROM Dept
6 WHERE DeptName ='總公司'
7 UNIONALL
8 SELECT Dept.DeptID, Dept.DeptName, Dept.ParentDeptID
9 FROM Dept, Dept_Head
10 WHERE Dept.ParentDeptID = Dept_Head.DeptID
11 )
12 Select*FROM Dept_Head
13
1 CREATETABLE[NewTest]比較源表和目標表發現,有的記錄兩表中一致;有的兩表中部分一致;有的只存在源表中;有的只存在目標表中。我們需要以源表為標准來更新目標表。
2 (
3 [StudentID][bigint]NOTNULL,
4 [TestScore][decimal](4, 1) NOTNULL
5 ) ON[PRIMARY]
6 GO
7
8 INSERTINTO[NewTest]
9 VALUES (100001,90),
10 (100003,85.5),
11 (100004,77),
12 (101001,90),
13 (101002,90),
14 (101003,85.5),
15 (101004,88)
16 GO
17
1 MERGE Test
2 USING NewTest
3 ON Test.StudentID = NewTest.StudentID
4 WHEN MATCHED --記錄兩表匹配
5 THENUPDATESET Test.TestScore = NewTest.TestScore
6 WHENNOT MATCHED --記錄在目標表不存在
7 THENINSERTVALUES (NewTest.StudentID,NewTest.StudentID/1000, NewTest.TestScore)
8 WHENNOT MATCHED BY SOURCE --記錄在源表中不存在
9 THENDELETE
10 ;
11