Repository navigation
Expand file tree
/
Copy path23_SQL_Subqueries.sql
More file actions
284 lines (206 loc) · 5.82 KB
/
Copy path23_SQL_Subqueries.sql
File metadata and controls
284 lines (206 loc) · 5.82 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
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
--------------SQL Subqueries-------------
/*
Kategorie podzapytan on Dependency:
- Non-Correlated Subquery,
- Correlated Subquery,
Kategorie podzapytan on Result Types:
- Scalar,
- Row,
- Table,
Kategorie podzapytan on Location|Clauses
- SELECT,
- FROM,
- JOIN,
- WHERE,
*/
SELECT
AVG(Sales)
FROM Sales.Orders -- Scalar query (jedna kolumna, jeden wiersz)
SELECT
OrderID
FROM Sales.Orders -- Row query (jedna kolumna, wiele wierszy)
SELECT
OrderID,
OrderDate
FROM Sales.Orders -- Table query (wiele kolumn, wiele wierszy)
--------Subquery in FROM clause------
/*
FROM Subquery - uzywamy jako tymczasowas tabele dla Main Query
SYNTAX:
SELECT column1,column2,...
FROM (SELECT column FROM table WHERE condition) AS alias
*/
/*task: Find the products that have higher than the average price of
all products*/
SELECT*
FROM(
SELECT
ProductID,
Price,
AVG(Price) OVER() [srednia]
FROM Sales.Products
)t
WHERE Price > srednia
/*task: Rank customers based on their total amount of sales*/
SELECT
t.*, -- trzeba dac alias po tabeli z ktorej wydobywamy czyli w tym przydapdku t
RANK() OVER(ORDER BY suma DESC) [ranking]
FROM(
SELECT
CustomerID,
SUM(Sales) [suma]
FROM Sales.Orders as o
GROUP BY CustomerID
)t
--------Subquery in SELECT clause--------
/*
Uzywamy SELECT podzapytan aby zaagregowac dane obok siebie
z danymi z glownego zapytania, co pozwala na bezposrednie
porownanie.
SYNTAX:
SELECT
Column1,
(SELECT column FROM table1 WHERE condition) AS alias
FROM table1
ZASADA: inner zapytanie musi byc podzapytaniem skalarnym.
*/
/*task: Show the product IDs, names, prices and total number
of orders*/
SELECT
p.*,
(SELECT COUNT(*) FROM Sales.Orders) AS TotalOrders
FROM Sales.Products as p;
--------JOIN Subquery-------
/*
Uzywa sie tego by przygotowac dane (filtrujac lub agregujac)
przed joinowania go z innymi tabelami.
*/
/*task: Show all customer details and fing the total orders of
each customer*/
SELECT
c.*,
o.TotalOrders
FROM Sales.Customers as c
LEFT JOIN (
SELECT
CustomerID,
COUNT(*) TotalOrders
FROM Sales.Orders
GROUP BY CustomerID) o
ON c.CustomerID = o.CustomerID
--------WHERE Subquery-------
/*
Uzywa sie dla bardziej skomplikowanej logiki filtrowania danych
i sprawia ze zapytanie jest bardziej elastyczne i dynamiczne.
COMPARISON OPERATORS: uzywamy aby porownac dwie wartosci
<,>,=,!=,>=,<=
LOGICAL OPERATORS:
IN ANY ALL EXISTS
SYNTAX comparison operators:
SELECT column1, column2,...
FROM table1
WHERE column = (SELECT column FROM table2 WHERE condition) musi to byc skalar
*/
/*task: Find the products that have a price higher than the averaged
price of all products*/
SELECT
p.*,
(SELECT AVG(Price) [srednia] FROM Sales.Products) [srednia]
FROM Sales.Products as p
WHERE Price > (SELECT AVG(Price) [srednia] FROM Sales.Products)
SELECT
AVG(Price) [srednia]
FROM Sales.Products
---------IN Opertaror---------
/*
Sprawdza czy wartosc pasuje do jakielkolwiek wartosci
z listy.
SYNTAX:
SELECT column1, column2,...
FROM table1
WHERE column IN (SELECT column FROM table2 WHERE condition) NIE musi to byc skalar!
*/
/*task: Show the details of orders made by customers in Germany*/
SELECT*
FROM Sales.Orders
WHERE CustomerID IN (SELECT CustomerID FROM Sales.Customers WHERE Country = 'Germany')
-- w analogicznym przykladzie gdzie chcemy zwrocic wszystkich ale nie Niemcow,
-- mozemy uzyc != albo NOT IN
----------ANY & ALL Subqueries---------
/*
ANY - sprawdza czy wartosc jest taka sama jak jakakolwiek wartosc z listy.
Uzywa sie zeby sprawdzic czy wartosc jest prawdziwe dla chociaz jednej wartosci
z listy.
ALL - sprawdza czy wartosc pasuje do wszystkich wartosci z listy.
SYNTAX:
SELECT column1, column2,...
FROM table1
WHERE column < ANY (SELECT column FROM table2 WHERE condition)
*/
/*task: Find female employees whose salaries are greater than the
salaries of any male employees */
SELECT
EmployeeID,
CONCAT(TRIM(FirstName),' ', TRIM(LastName)) [imie i nazwisko],
Salary
FROM Sales.Employees
WHERE
Gender = 'F'
AND Salary > ANY
(SELECT
Salary
FROM Sales.Employees
WHERE Gender = 'M')
/*task: Find female employees whose salaries are greaten than the
salaries of all male employees */
SELECT
FirstName,
ISNULL(LastName,'Kowalska') [Nazwisko],
Salary
FROM Sales.Employees
WHERE Gender = 'F'
AND Salary > ALL
(SELECT Salary FROM Sales.Employees WHERE Gender = 'M')
----------Dependencies of Subqueries----------
/*
Non-Correlated Subquery - podzapytanie ktore moze dzialac niezaleznie od Main Query
(mozna wykonac bez Main Query)
Zostanie wykonane tylko raz i wynik bedzie uzyty przez Main Query
Better performance.
For static comparisons.
Correlated Subquery - podzapytanie krote polega na wartosciach z Main Query
(nie mozna wykonac bez Main Query)
Podzapytanie bedzie wykonywane dla kazdego wiersza (ktore Main Query przeprocesuje).
Bad performance.
For row-by-row comparisons or Dynamic Filtering
*/
/*task: Show all customer details and find the orders for each customer*/
SELECT
c.*,
ISNULL(licznik,0) [licznik]
FROM Sales.Customers as c
LEFT JOIN (SELECT CustomerID,COUNT(*) as [licznik] FROM Sales.Orders GROUP BY CustomerID) as o
ON c.CustomerID = o.CustomerID
SELECT
*,
(SELECT COUNT(*) [count] FROM Sales.Orders as o WHERE o.CustomerID = c.CustomerID) [totalSales]
-- tu jak damy zamiast c.CustomerID np. 1 albo 2 to count zliczy nam ile zamowien ma dany klient
FROM Sales.Customers as c
------------EXISTS-----------
/*
Sprawdza czy podzapytanie zwraca jakies wiersze.
SYNTAX:
SELECT column1, column2,...
FROM Table2
WHERE EXISTS (SELECT 1
FROM Table1)
WHERE Table.ID = Table2.ID)
*/
/*task: Show the order datails for customers in Germany*/
SELECT
OrderID,
CustomerID,
OrderDate
FROM Sales.Orders as o
WHERE EXISTS(SELECT 1 FROM Sales.Customers as c WHERE o.CustomerID = c.CustomerID AND c.Country = 'Germany')
-- mozna dac NOT przed EXISTS i wtedy dostaniemy wszytkich nieNiemcow