-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLesson4.sql
334 lines (326 loc) · 8.71 KB
/
Lesson4.sql
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
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
--INTESRECT, EXCEPT
--except is good when trying to compare two tables
-- We can check previous query with except. Same 72 rows are returned
SELECT p.Name, p.ProductID
FROM Production.Product p
WHERE NOT EXISTS (
SELECT *
FROM Production.ProductInventory i
WHERE p.ProductID = i.ProductID)
GO
SELECT ProductID
FROM Production.Product p
EXCEPT
SELECT ProductID
FROM Production.ProductInventory
GO
--Finding out which ages are missing in the second table
--using order by
SELECT age
FROM Employees
EXCEPT
SELECT age
FROM management
ORDER BY age
GO
-- it returns distinct rows not columns
-- it checks the combination of two columns
SELECT lastname, age
FROM Employees
SELECT lastname, age
FROM management
ORDER BY age
GO
SELECT lastname, age
FROM Employees
EXCEPT
SELECT lastname, age
FROM management
ORDER BY age
GO
--Finding out which names are different in the second table Johnson 32 is the only one that is present in table management
SELECT name
FROM Employees
EXCEPT
SELECT name
FROM management;
GO
--checking which names are existing in both tables
SELECT name
FROM Employees
INTERSECT
SELECT name
FROM management;
GO
/*We can find out there are products that where not sold when comparing
SELECT * FROM Production.Product
SELECT * FROM Sales.SalesOrderDetail*/
SELECT * FROM Production.Product
SELECT * FROM Sales.SalesOrderDetail
GO
SELECT
ProductID
FROM
Production.Product
EXCEPT
SELECT
ProductID
FROM
Sales.SalesOrderDetail;
GO
--We can check the names of products that are not currently sold
SELECT ProductID, Name FROM Production.Product
WHERE ProductID IN (346, 1, 369,
532, 413, 358, 323, 398,
534, 447, 321, 403, 495,
348, 847, 385, 376, 746,
520, 381, 829, 481, 361,
408, 331, 380, 812, 318, 363,
329, 3, 535, 427, 508, 437, 320, 419,
901, 517, 349, 480, 737, 453, 451, 845
)
--There are no sold items that are missing in Production.Product table
SELECT
ProductID
FROM
Sales.SalesOrderDetail
EXCEPT
SELECT
ProductID
FROM
Production.Product
GO
--INTERSECT
SELECT
ProductID
FROM
Production.Product
INTERSECT
SELECT
ProductID
FROM
Sales.SalesOrderDetail;
GO
-- 504 rows of ProductID of which there are 238 WorkOrders
SELECT ProductID
FROM Production.Product
INTERSECT
SELECT ProductID
FROM Production.WorkOrder ;
--the intersect allows to find if the managers in employee table
--get the same salary as in managers table
SELECT position, salary
FROM employees
INTERSECT
SELECT position, salary
FROM management
SELECT * FROM employees
SELECT * FROM management
--Creating Stored Procedure
CREATE PROCEDURE EmployeeSalaryhistory
AS
BEGIN
SELECT E.LoginID, P.Rate FROM [HumanResources].[Employee] AS E
INNER JOIN [HumanResources].EmployeePayHistory AS P
ON E.BusinessEntityID = P.BusinessEntityID
END
EXEC EmployeeSalaryhistory
GO
--Alter Stored Procedure or do it with the help of UI
ALTER PROCEDURE EmployeeSalaryhistory
AS
BEGIN
SELECT TOP 10 E.LoginID, P.Rate FROM [HumanResources].[Employee] AS E
INNER JOIN [HumanResources].EmployeePayHistory AS P
ON E.BusinessEntityID = P.BusinessEntityID
END
GO
DROP PROCEDURE EmployeeSalaryhistory;
--Stored Porcedures with paramaters: adding a parameter of the list price
CREATE PROCEDURE uspFindProducts (@min_list_price AS DECIMAL)
AS
BEGIN
SELECT
Name,
ListPrice
FROM
Production.Product
WHERE
ListPrice >= @min_list_price
ORDER BY
ListPrice;
END;
GO
--executing the stored procedure will return all the list prices bigger than parameter
EXEC uspFindProducts 50
GO
--Alter Procedure with adding parameter @prefered_colour AS VARCHAR(50)
ALTER PROCEDURE [dbo].[uspFindProducts](@min_list_price AS DECIMAL, @prefered_colour AS VARCHAR(50))
AS
BEGIN
SELECT
Name, Color,
ListPrice
FROM
Production.Product
WHERE
ListPrice >= @min_list_price
AND Color = @prefered_colour
ORDER BY
ListPrice;
END;
EXEC uspFindProducts 50, Black
GO
DROP PROCEDURE uspFindProducts
SELECT * FROM Production.Product
GO
--CTE Common Table Expressions allows you to define a temporary named result set
--let's asume each employee has a manager with the same id
WITH employee_manager AS (
SELECT e.name AS employee_name, e.lastname AS employee_lastname, m.name AS manager_name, m.lastname AS manager_lastname
FROM employees e
LEFT JOIN management m ON e.employee_id = m.manager_id
)
SELECT employee_name, employee_lastname, manager_name, manager_lastname
FROM employee_manager;
--LESSON 14
--Making CTE from older subqueries to use those again
--Finding product names that have no inventory
--in the cte the number and name of the columns should be the same as in expression
WITH exhausted_inventory (Name, ProductID)
AS
(SELECT p.Name, p.ProductID
FROM Production.Product p
WHERE NOT EXISTS (
SELECT *
FROM Production.ProductInventory i
WHERE p.ProductID = i.ProductID))
SELECT * FROM exhausted_inventory
WHERE Name LIKE '%Mountain%'
GO
--multiple cte's in one code block helps to make the code easier to understand
--in here we are creating two cte one from inventory another from sales
--we find out how many do we have of expensive product and how many have been sold
WITH inventory_stack
AS
(SELECT ProductID, Quantity, LocationID
FROM Production.ProductInventory),
expensive_products
AS
(SELECT ProductID, OrderQty, UnitPrice FROM [Sales].[SalesOrderDetail]
WHERE UnitPrice > 1000)
SELECT TOP 100 i.Quantity, i.LocationID, e.OrderQty, e.UnitPrice FROM inventory_stack i
INNER JOIN expensive_products e
ON i.ProductID=e.ProductID
--recursive CTE
WITH number_sequence (n) AS (
-- Anchor member
SELECT 1 as n
UNION ALL
-- Recursive member
SELECT n + 1
FROM number_sequence
WHERE n < 10
)
SELECT n
FROM number_sequence;
-- recursive Factorial
--n! =n*(n-1)! or (n+1)n!
WITH ctefatorial as
(SELECT 1 AS n, 1 AS fact --anchor part
UNION ALL
SELECT n+1, (n+1) * fact --recursive part
FROM ctefatorial
WHERE n<5) --termination check
SELECT n, fact FROM ctefatorial --calling
-- Another case of recursive CTE looping weekdays
WITH cte_numbers(n, weekday)
AS (
SELECT
0,
DATENAME(DW, 0)
UNION ALL
SELECT
n + 1,
DATENAME(DW, n + 1)
FROM
cte_numbers
WHERE n < 6
)
SELECT n,
weekday
FROM
cte_numbers;
--Case statements
/*CASE case_value
WHEN when_value THEN statement_list
[WHEN when_value THEN statement_list] …
[ELSE statement_list]
END CASE*/
-- order quantity big or small
SELECT TOP 1000 [SalesOrderDetailID], OrderQty,
CASE
WHEN OrderQty > 3 THEN 'The quantity is greater than 3'
WHEN OrderQty = 3 THEN 'The quantity is 3'
ELSE 'The quantity is under 3'
END
AS QuantityText
FROM [Sales].[SalesOrderDetail]
--CASE Statement With aggregate functions ORDER BY Clause
SELECT StateProvinceID,
CASE
WHEN COUNT(Person.Address.City) > 20 THEN 'manycandidates'
ELSE 'need more promotion'
END As persons_by_province
FROM [AdventureWorks2019].[Person].[Address]
GROUP BY StateProvinceID
--Advanced case
--Retrieving employees with their hire date and department
--WITH JOIN
SELECT e.BusinessEntityID, e.NationalIDNumber, e.LoginID, e.Jobtitle, e.HireDate, d.EndDate as enddate, tenureinyears =
CASE
WHEN DATEDIFF(YEAR, HireDate, DateADD(year,-9,GETDATE()))>= 5 THEN '5+'
WHEN DATEDIFF(YEAR, HireDate, DateADD(year,-9,GETDATE()))>= 3 THEN '3-4'
WHEN DATEDIFF(YEAR, HireDate, DateADD(year,-9,GETDATE()))= 1 THEN '1-2'
ELSE 'Less Than Year'
END
FROM HumanResources.Employee e
LEFT JOIN HumanResources.EmployeeDepartmentHistory D
ON d.BusinessEntityID=e.BusinessEntityID
GO
-- selecting the one's who are still workig by selecting only the rows where end date is null
SELECT e.BusinessEntityID, e.NationalIDNumber, e.LoginID, e.Jobtitle, e.HireDate, d.EndDate as enddate, tenureinyears =
CASE
WHEN DATEDIFF(YEAR, HireDate, DateADD(year,-9,GETDATE()))>= 5 THEN '5+'
WHEN DATEDIFF(YEAR, HireDate, DateADD(year,-9,GETDATE()))>= 3 THEN '3-4'
WHEN DATEDIFF(YEAR, HireDate, DateADD(year,-9,GETDATE()))= 1 THEN '1-2'
ELSE 'Less Than Year'
END
FROM HumanResources.Employee e
LEFT JOIN HumanResources.EmployeeDepartmentHistory D
ON d.BusinessEntityID=e.BusinessEntityID
WHERE d.EndDate IS NULL
SELECT ProductID, OrderQty, UnitPrice,
CASE
WHEN OrderQty > 1 THEN lineTotal
ELSE UnitPrice
END AS total
from Sales.SalesOrderDetail
SELECT ProductID, OrderQty, UnitPrice, LineTotal
from Sales.SalesOrderDetail
GO
--opposite case
SELECT ProductID, OrderQty, UnitPrice,
CASE
WHEN OrderQty > 1 THEN UnitPrice
ELSE LineTotal
END AS total
from Sales.SalesOrderDetail
GO
--tempoary table
-- Create a local temporary table
CREATE TABLE #tempTable (column1 INT, column2 VARCHAR(50));
-- Insert data into the temporary table
INSERT INTO #tempTable VALUES (1, 'Value 1'), (2, 'Value 2');
-- Select data from the temporary table
SELECT * FROM #tempTable;