Repository navigation
Expand file tree
/
Copy path21_SQL_Ranking-window-functions.sql
More file actions
221 lines (169 loc) · 4.46 KB
/
Copy path21_SQL_Ranking-window-functions.sql
File metadata and controls
221 lines (169 loc) · 4.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
------------SQL Ranking Functions-------------
/*
Rank Functions Syntax:
Rank() OVER(PARTITION BY ProductID ORDER BY Sales)
- expression inside a rank function must be empty
- PARTITION BY jest opcjonalne
- ORDER BY jest wymagane
- FRAME nie jest dozwolony w ranking functions
*/
--------ROW_NUMBER()-------
/*
Przypisuje unikalny numer do kazdego z wierszy.
Ta funkcja nie rozstrzyga remisow.
*/
/*task: Rank the orders based on their sales from
highest to the lowest */
SELECT
OrderID,
Sales,
ROW_NUMBER() OVER(ORDER BY Sales DESC) [Ranking]
FROM Sales.Orders
---------RANK()---------
/*
Przypisuje range to kazdego wiersza.
Obsluguje remisy. Moze zostawiac dziury w rankingu.
*/
/*task: Rank the orders based on their sales from
highest to the lowest */
SELECT
OrderID,
Sales,
RANK() OVER(ORDER BY Sales DESC) [Ranking]
FROM Sales.Orders
---------DENSE_RANK()--------
/*
Przypisuje range to kazdego wiersza.
Obsluguje remisy. Nie zostawia dziur w rankingu.
*/
/*task: Rank the orders based on their sales from
highest to the lowest */
SELECT
OrderID,
Sales,
DENSE_RANK() OVER(ORDER BY Sales DESC) [Ranking]
FROM Sales.Orders
---USE CASE: TOP N-Analysis---
/*task: Find the top highest sales for each product*/
SELECT
ProductID,
Sales
FROM(
SELECT
ProductID,
Sales,
ROW_NUMBER() OVER(PARTITION BY ProductID
ORDER BY Sales DESC) [pozycja]
FROM Sales.Orders
)t
WHERE pozycja = 1;
---USE CASE: BOTTOM N-Analysis---
/*task: Find the lowest 2 customers based on their total sales*/
SELECT*
FROM (
SELECT
CustomerID,
SUM(Sales) as faktycznieTrzeba, --- jesli zaznaczmy * to kazda kolumna musi miec swoja nazwe
ROW_NUMBER() OVER(ORDER BY SUM(Sales)) [ranking] -- to dziala bo WF(X) dzialaja z GROUP BY
--jesli uzywaja tego samego co jest w reszcie selekta i akceptuje to group by
FROM Sales.Orders
GROUP BY CustomerID
)t
WHERE ranking <= 2
---USE CASE: Generate Unique IDs---
/*task: Assign unique IDs to the rows of 'Order Archive' table */
SELECT
ROW_NUMBER() OVER(ORDER BY OrderDate) [unique ids],
OrderID,
ProductID,
Sales
FROM Sales.OrdersArchive
---USE CASE: Identify Duplicates---
/*task: Identify duplicater rows in the table 'OrdersArchive'
and return a cleasn result without any duplicates */
SELECT*
FROM(
SELECT
ROW_NUMBER() OVER(PARTITION BY OrderID ORDER BY CreationTime DESC) [rn],
OrderID,
ProductID,
Sales
FROM Sales.OrdersArchive -- jesli rank jest powyzej jednynki to PK nie jest unikalny
)t
WHERE rn = 1;
----------NTILE()---------
/*
Dzieli dane na podane liczbe mniej wiecej takich samych grup (buckets)
Bucket size = Number of Rows / Number of Buckets
SQL RULE
Wieksze grupy sa pierwsze.
*/
SELECT
OrderID,
Sales,
NTILE(1) OVER(ORDER BY Sales DESC) [one bucket],
NTILE(2) OVER(ORDER BY Sales DESC) [two bucket],
NTILE(3) OVER(ORDER BY Sales DESC) [three bucket],
NTILE(4) OVER(ORDER BY Sales DESC) [four bucket]
FROM Sales.Orders
----USE CASE: Data Segmentation----
/*task: Segment all orders into 3 categories high, medium and low sales*/
SELECT
Sales,
rn,
CASE
WHEN rn = 1 THEN 'HIGH'
WHEN rn = 2 THEN 'MEDIUM'
ELSE 'LOW'
END [categories]
FROM(
SELECT
NTILE(3) OVER(ORDER BY Sales DESC) [rn],
Sales
FROM Sales.Orders
)t
----USE CASE: Equalizing Loads----
/*task: In order to export the data, divide the orders into 2 groups*/
SELECT
NTILE(2) OVER(ORDER BY OrderID) [ntile],
* -- ta gwiazdke mozna dac na koncu i bedzie to dzialac, ew mozna dac przed ale trzeba wzkazac
-- tabele czyli: Sales.Orders.*,
FROM Sales.Orders
-------CUME_DIST()-------
/*
Cumulative distribution - rozklad skumulowany.
Kalkuluje dystrybujce punktow danych w obrebie okna.
CUME_DIST() = Position Number / Number of Rows
TIE RULE! - pozycja ostatniego wystapienia tej samej
wartosci jest brana pod uwage.
*/
SELECT
OrderID,
Sales,
CUME_DIST() OVER(ORDER BY Sales DESC) [CUME_DIST()]
FROM Sales.Orders
------PERCENT_RANK()-------
/*
Kalkuluje relatywna pozycje kazdego wiersza.
Percent_Rank = Position Number - 1 / Number of Rows - 1
TIE RULE! - pozycja pierszego wystapienia tej samej wartosci
jest brana pod uwage.
*/
SELECT
OrderID,
Sales,
ROUND(PERCENT_RANK() OVER(ORDER BY Sales),2) [Pr]
FROM Sales.Orders
/*task: Find the products that fall within the hightest 40% of the prices*/
SELECT
*,
CONCAT(CD * 100, '%') DistRankPerc,
CONCAT(PR * 100, '%') PercentRankPerc
FROM(
SELECT
Product,
Price,
CUME_DIST() OVER(ORDER BY Price DESC) [CD],
PERCENT_RANK() OVER(ORDER BY Price DESC) [PR]
FROM Sales.Products
)t WHERE CD <= 0.4