2. Covered Topics
Part-1
• Intro to Structure Query Language
• What is SQL
• Bit about relational databases
• How tables communicate
• Basic Operations
• Selection commands
• Comparison operators
• Multiple conditions
• IS NULL & IS NOT NULL
• LIKE & NOT LIKE
• BETWEEN & IN Operator
• Aggregate Functions
• SUM
• AVERAGE
• MIN
• MAX
• Grouping, Having & Order By
• Group By
• Having
• Order By
• JOINS
• Inner
• Left
• Right
• Full Joins
• Union Clause
• Intersection Clause
• Misc Commands
• Top Clause
• CAST
Part-2
3. Covered Topics
Part-3
• CASE Statements
• Date Functions
• SUB-QUERIES
• FROM Subquery
• WHERE Subquery
• SELECT Subqueries
• WITH Clause (Common Table Expressions (CTEs))
• OLAP Operators
• CUBE Operator
• ROLL UP Operator
• GROUPING SETS
• Window Functions
• Stored Procedures
Part-4
6. • A relational database is a set of tables (datasets with rows and
columns) that contain information relating to other tables in the
database. As the company grows and record thousands (or millions) of
orders, storing data in separate tables helps to optimize for space.
• Data in separate tables helps to optimize for space.
• Example:
10. • SELECT *
FROM table_name;
OR
• SELECT column_name1,
column_name2……
FROM table_name;
Example 1:
• SELECT *
FROM Production.ProductDescription;
Practice Question(s) :
1.Select columns ProductDescriptionID, Description &
ModifiedDate from table Production.ProductDescription in
the specified order.
SELECTION COMMAND – Syntax/Practice
A * after the SELECT
command signifies that all
columns in the table are
being called.
* can be replaced by column
names in order to limit your
selection. The order in
which the column names
are called DOES NOT matter
12. • SELECT *
FROM table_name
WHERE column_name = ‘A specific condition is met’;
Example 1:
• SELECT *
FROM person.person WHERE BusinessEntityID =32;
Practice Questions:
1. Find all the records in table Purchasing.PurchaseOrderDetail where column ReceivedQty is equal or
greater than 500.
2. Write a SQL query to find all the records in table Purchasing.PurchaseOrderDetail where column ProductID
is equal or less than 300.
3. Find all the records in table Purchasing.ProductVendor where column UnitMeasureCode is equal to ‘CAN’.
4. Write a SQL query to find all the records in table Sales.SpecialOffer where column Type is equal to ‘No
Discount’.
SELECTION COMMAND WITH WHERE – Syntax/Practice
TIP:
Comparison operators Like >, <
and = can be used to execute
conditional statements
14. • SELECT *
FROM table_name
WHERE column_name = ‘Condition 1 is met’ AND/OR
column_name = ‘Condition 2 is met’;
Example 1:”
• SELECT *
FROM Sales.SpecialOffer WHERE DiscountPct >=0.15 AND Category = 'Reseller’;
Practice Questions:
1. Find all the records in table Sales.SpecialOffer where column DiscountPct is less or equal to 0.2 (20%) AND
Category is equal to ‘Reseller’ AND type = ‘Seasonal Discount’.
2. Find all the records in table Production.TransactionHistory where column ReferenceOrderID is greater or
equal to 5000 OR TransactionID is less than or equal to 100200
3. Find all the records in table Sales.Store where BusinessEntityID is greater or equal than 312 OR Name is
equal to ‘Areas Bike Accessories’
SELECTION COMMAND WITH WHERE + AND/OR – Syntax/Practice
16. • SELECT *
FROM table_name
WHERE column_name IS NULL/NOT NULL;
Example 1:
• SELECT *
FROM Sales.Customer WHERE PersonID IS NULL;
Practice Questions:
1. Find all the records in table Sales.Customer where column StoreID is greater or equal to 1000
AND PersonID IS NULL.
2. Find all the records in table Sales.SalesOrderDetail where column CarrierTrackingNumber IS
NOT NULL OR LineTotal is less than or equal to 2000
3. Find all the records in table Sales.SpecialOffer where MaxQty IS NOT NULL AND Category is
‘Reseller’
WHERE + IS NULL/IS NOT NULL – Syntax/Practice
18. • SELECT *
FROM table_name
WHERE column_name LIKE/NOT LIKE;
Example 1:
• SELECT *
FROM Purchasing.Vendor WHERE Name LIKE ('e%’);
Practice Questions:
1. Find all the records in table Purchasing.Vendor where column Name starts with A.
2. Find all the records in table Purchasing.Vendor where column Name ends with D.
3. Find all the records in table Purchasing.Vendor where column Name does not have NG in them.
4. Find all the records in table Purchasing.Vendor where column Name has ‘r’ in third position.
5. Find all the records in table Purchasing.Vendor where column Name does not start with ‘g’ and ends with ‘y’.
WHERE + LIKE/NOT LIKE – Syntax/Practice WILD CARD Operators
a% Values that start with ‘a’
%a Values that end with ‘a’
%ef% Values that have ‘ef’ in any
position
‘_r%’ Values that have ‘r’ in 2nd
position
‘E_%’ Values that start with E and
have at least 2 characters
‘A__%’ Values that start with A and
have at least 3 characters
‘A%o’ Values that start with A and
end with o
20. • SELECT *
FROM table_name
WHERE column_name BETWEEN value 1
AND value 2;
Example 1 (Between):
• SELECT * FROM Purchasing.Vendor WHERE CreditRating BETWEEN 2 AND 4;
Example 2 (IN):
• SELECT * FROM Purchasing.Vendor WHERE CreditRating IN (2,3,4);
Practice Questions:
1. Select all records from Table Person.EmailAddress where column BusinessEntityID is between 30 to 50
2. Select all records from Table Person.EmailAddress where column BusinessEntityID is 30,35,36,37,45,48,70
BETWEEN – Syntax/Practice
22. • SELECT COUNT/SUM(column_name)
FROM table_name;
Example 1 (COUNT):
• SELECT COUNT(*) FROM purchasing.Vendor;
Example 2 (SUM):
• SELECT SUM(Quantity) FROM Production.TransactionHistory;
Practice Questions:
1. Find SUM of column Quantity in table Production.TransactionHistory where TransactionType is ‘S’ .
Call the column SUMQty
2. Find SUM of column ActualCost in table Production.TransactionHistory where TransactionType is
‘W’. Call the column SUMActualCost
3. Find COUNT of records in table Production.TransactionHistory where TransactionType is ‘W’. Call
the column TotalRecords
COUNT & SUM – Syntax/Practice
Running this script
generates a result which
lacks a column name.
Aliasing can solve this
problem by include AS
NewName
23. • SELECT AVG/MIN/MAX(column_name)
FROM table_name;
Example 1 (Average):
• SELECT AVG(UnitPrice) AS AVGUnitPrice
FROM Sales.SalesOrderDetail;
Practice Questions:
1. Find Average of column LineTotal in table Sales.SalesOrderDetail where LineTotal is less than 3000 .
Call the column AVGLineTotal
2. Find Average of column LineTotal in table Sales.SalesOrderDetail where ProductID is BETWEEN 700 &
800 . Call the column AVGLineTotal
3. To the above calculated data please add the clause of SpecialOfferID = 2
4. Also add the MIN & MAX of LineTotal in the above calculated expressions.
AVERAGE,MIN &MAX – Syntax/Practice
Similarly, the Min/Max of
UnitPrice column can also
be calculated
25. • SELECT
column_1,
SUM/MIN/MAX/AVERAGE(column_name)
FROM table_name
GROUP_BY column_1;
Example 1 (GROUP BY):
• SELECT
ProductId, AVG(LineTotal) AS AVGLineTotal,
MIN(LineTotal) AS MINLineTotal, MAX(LineTotal) AS MAXLineTotal
FROM Sales.SalesOrderDetail GROUP BY ProductId;
GROUP BY – Syntax/Practice
Before proceeding further, it
is important to understand
the application/use case of
GROUP BY
26. GROUP BY – Practice
1. Calculate the SUM of UnitPrice and AVG of UnitPrice grouped based on
SpecialOfferID from table Sales.SalesOrderDetail
2. Add the AVG UnitPriceDiscount to the calculations above as AVGUnitPriceDiscount
3. Calculate the AVG ExpMonth on CardType in table Sales.CreditCard. Do the results
make sense and can these results be validated
27. • SELECT
column_1,
SUM/MIN/MAX/AVERAGE(column_name)
FROM table_name
GROUP_BY column_1
HAVING Condition_1… ;
Example 1 (GROUP BY):
1. Calculate the Average Line Total (as AVGLineTotal) , Minimum Line Total (as MINLineTotal)
and Maximum Line Total (as MAXLineTotal) from Sales.SalesOrderDetail grouped by
ProductID and filtered where AVGLineTotal > 2000
GROUP BY + HAVING – Syntax/Practice
In order to implement any
CONDITIONAL LOGIC on the
results of GROUP BY we
must use HAVING as WHERE
will not work
28. HAVING – Practice
1. Using the table, Sales.SalesOrderDetail calculate the SUM of LineTotal as
SUMLineTotal grouped by SalesOrderID. Filter the result where the SUMLineTotal
is between 599 and 3000
2. Alter the query above in order to get results where the SUMLineTotal is <=789
3. Using the table Production.WorkOrder calculate the SUM of OrderQty, SUM of
StockedQty and group them on WorkOrderID and then filter the results for SUM of
OrderQty greater than 10 and SUM of StockedQty less than 15
29. • SELECT *
FROM table_name
ORDER BY column_name DESC;
OR
• SELECT
column_1,
SUM/MIN/MAX/AVERAGE(column_name)
FROM table_name
GROUP_BY column_1
HAIVING Condition_1…
ORDER BY column_name DESC;
ORDER BY – Syntax/Practice
The default state of the
ORDER BY command is ASC
order. In order to sort to do
it based on DESC the word
DESC needs to be specified.
32. What are Joins?
1. JOINS allow you make different tables speak together.
2. Using Primary and Secondary Keys, tables can then be joined together using different types of
joins.
3. JOINS allow us to bring together distributed databases in order to gain greater insights
INNER JOIN LEFT JOIN RIGHT JOIN FULL JOIN
33. • SELECT
column1_from-table1
column1_from-table2
FROM table1
LEFT/RIGHT/INNER JOIN table2 ON
table_1.primary_key_column = table_2.foreign_key_column
Example 1 (LEFT JOIN):
1. Creating a left join between Sales.Customer and Sales.SalesTerritory
• SELECT
Customer.StoreID,
SalesTerritory.Name,
SalesTerritory.SalesYTD
FROM Sales.Customer
LEFT JOIN Sales.SalesTerritory ON
Customer.TerritoryID = SalesTerritory.TerritoryID;
JOINS– Syntax
34.
35. JOINS – Practice
1. Create a LEFT JOIN between tables Person.Address and Person.StateProvince using
StateProvinceID as a Key. Display the following columns in this join:
• AddressLine1 from Address
• AddressLine2 from Address
• Name from StateProvince
2. What is total COUNT of rows in the table above?
3. Convert this JOIN to a RIGHT JOIN?
4. What is total COUNT of rows now in the RIGHT JOINED table?
37. • SELECT *
FROM table1
UNION OR UNION ALL
SELECT *
FROM table1
Questions to Consider (Unions):
1) How are UNIONS different from JOINS
2) JOIN Example
3) UNION & UNION ALL Example
(Contd…)
UNIONS– Syntax
38. (Contd…)
Example 1 (UNION):
Creating a UNION between HumanResources.Department and Person.Address
SELECT *
FROM HumanResources.Department
UNION
SELECT *
FROM Person.Address;
Example 2 (UNION):
Creating a UNION between HumanResources.Department and HumanResources.Department
SELECT *
FROM HumanResources.Department
UNION
SELECT *
FROM HumanResources.Department;
** Lets also try the same query with a UNION ALL command.
40. SOME IMPORTANT COMMANDS & FUNCTIONS
• SELECT
* FROM INFORMATION_SCHEMA.COLUMNS
• SELECT DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_SCHEMA = 'Person' AND
TABLE_NAME = 'Person' AND
COLUMN_NAME = 'LastName';
Fetch key information about
the different tables and their
columns.
Determine data type of a
column one columns at a time.
42. Example 1 (ALL):
• SELECT TOP 30 *
FROM Sales.SalesOrderDetail
Practice (Top):
1. The company is interested in identifying the names of their top
30 performing products in terms of Revenue (Line Total).
2. How about the Top 15% in terms of Revenue (Line Total).
3. Furthermore, the company is also interested in top 10 and top
10% performing Subcategories.
TOP – Syntax
TOP fetches the N number of
records from a selected table
and can also be used with
PERCENT.
ORDER BY can be used to get
TOP N output based on the
values of a particular column
44. SYNTAX (CAST):
• SELECT
CAST (Column_name AS datatype),
CAST (Column_name AS datatype)
FROM Sales.SalesOrderDetail
Practice (CAST):
1. Using the Sales.CurrencyRate table CAST AverageRate as type
integer, CurrencyRateDate as Date, CurrencyRateDate as Time and
CurrencyRateDate as int. Do you see any difference especially
when it comes to CASTING the time variables.
CAST– Syntax CAST allows for changing the
data type of a particular
column and display it as a
separate result/column. The
original column and its type
remains the same
46. SYNTAX (CASE):
• SELECT
Column_1,Column_2
CASE WHEN Column_N = ‘A specific condition’ THEN ‘Attach a behavior’
ELSE ‘Attach another behavior’ END AS ‘Give column a name’
FROM Table_Name;
Example (CASE):
1. Join tables Sales.SalesOrderDetail and Production.Product in order
to produce a list of LineTotals Grouped By Product Name. Once this
list is generated use the LineTotals in order to generate a
Categorical column/variables that categorizes the per product sales
into three buckets (Poor Performance, Average Performance, Great
Performance).
CASE– Syntax
CASE Statements can be
considered as the IF-
THEN_ELSE statements in SQL
47. CASE – Practice
1.From the table Sales.Customer create a column Test that
displays the PersonID when it is NOT NULL and displays the
TerritoryID when the PersonID IS NULL.
2.From the table Sales.SalesOrderDetail find the sum of
LineTotal grouped based on SalesOrderID. Once achieved
categorize these results into 4 categories of your choice.
3.From the table Production.WorkOrderRouting find out the
sum of ActualCost grouped based on ProductID. Once
calculated order the results by ActualCost and then
categorize the data based on ActualCost into categories of
your choice.
48. CASE – Practice
1.From the table Sales.Customer create a column Test
that displays the PersonID when it is NOT NULL and
displays the TerritoryID when the PersonID IS NULL.
50. Subqueries Advantages Vs Disadvantages
Advantages
• Subqueries structure a complex query
into isolated parts so that a complex
query can be broken down into a
series of logical steps for easy
understanding and code maintenance.
• Subqueries allow you to use the
results of another query in the outer
query.’
• In some cases, subqueries can replace
complex joins and unions and
subqueries are easier to understand.
Disadvantages
• Subqueries are computationally heavy
and complex subqueries can slow
down server performance
51. SYNTAX (FROM Subquery):
• SELECT
column_name
FROM ([Subquery])
Practice (FROM SUBQUERY):
1. Using the table, Sales.SalesOrderDetail write a query that separates
ProductID and finds the value of expression UnitPrice * OrderQty
Name this result as NewLineTotal. Then using the FROM subquery
method filter out the above results where LineTotal is greater than
20000.
2. From the table Production.TransactionHistory call all the records
where ActualCost is not 0 and TransactionType is ‘P’ or ‘S’, call
this result Subquery1. Filter the results of Subquery1 where actual
cost is greater than 2000.
FROM - Subquery Syntax The easiest of the subqueries is
the FROM subqueries
NOTE:
You cannot pass any
aggregations in the process of
filtering the results from the
FROM subquery. Let's try and
see what happens
52. SYNTAX (WHERE Subquery):
• SELECT
column_name
FROM Table_name
WHERE column_name OPERATOR ([Subquery])
Practice (WHERE SUBQUERY):
1. Select all the products in Sales.SalesOrderDetail table where the
product LineTotal is greater that the Average Line Total
2. Select all the records from Sales.SalesPerson table where the
SalesYTD greater than the Avg SalesYTD.
3. For the same table above calculate the difference between SalesYtd
and SalesLastYear. Calculate the average value of this difference
and then Select all the records in Sales.SalesPerson where the
calculated difference is lesser than the Average difference
WHERE - Subquery Syntax
A Subquery is also called a
nested query and always runs
first
53. SYNTAX (SELECT Subquery):
• SELECT
column_name,
([Subquery])
FROM Table_name
Practice (SELECT SUBQUERY):
1. Use the table, Sales.SalesOrderDetail in order to first calculate
and display the AVGLineTotal and then calculate the variance between
the LineTotal and the AVGLineTotal
SELECT - Subquery Syntax
A Subquery is also called a
nested query and always runs
first
55. WITH (CTE) Statement Premise + Syntax
• WITH clause is used for defining temporary relations/tables. The output of these
relation/tables is then available for use.
• WITH clause was introduced to standard SQL in order to simplify complex long
queries including those generated for producing JOINS and SUBQUERIES
• WITH CTEtable AS
(
-- a query –
)
SELECT *
FROM CTEtable
56. Example 1 (WITH):
• WITH testtable AS (
SELECT *
FROM Production.Product
WHERE ProductNumber LIKE 'Be%')
• SELECT *
FROM testtable;
USECASES/EXAMPLES (WITH):
1. We need to review the Products and LineTotals that are greater
than the average line total if SpecialOfferID equals 2?
2. Create a list of Product Names that will start with B using
the Product table. Based on this list we need to filter the
records in the SalesOrderDetail table.
WITH– Syntax
57. WITH – Practice
1. Review the Products and OrderQty (In Sales.SalesOrderDetail) that are greater than
the average OrderQty if SpecialOfferID equals 14
2. Use the WITH statement to create a JOIN between above calculated values and
Sales.SpecialOffer in order to see the actual Type, Category and DiscountPct
being filtered using the criteria passed in part 1.
59. DATE FUNCTIONS
DATE FUNCTION 1 BY 1 :
• GETDATE ---Gets todays date---
• MONTH ---Extracts the Month Number---
• DAY ---Extracts Day of the Month---
• YEAR ---Extracts the Year from a date---
• DATEDIFF ---Calculated Difference between two dates---
• DATEADD ---Added an year to current year---
• DATEFROMPARTS ---Insert Date with control over the parts (Year, Month, Date)---
• DATENAME ---Returns a Date/Year/Month/Day as a String Value---
• DATEPART ---Returns a Date/Year/Month/Day as an Integer---
• GETUTCDATE ---Returns a Coordinated Universal Time (UTC)---
• ISDATE ---Checks whether a Date is a Date Type or not, Returns 1 if true and 0
if False---
60. 1.The company wants to make its manufacturing process more efficient.
It wants to understand what Products are taking the most time to
produce (Calculate the number of days)?
1. In order to calculate this information, we will need to use
Production.WorkOrderRouting table
2. It is required that Actual Product Names from Production.Product table be used
for better identification
3. Calculate results for TOP 20 and TOP 20% of such products
Note: It would wise to break the problem down into different parts and
use WITH (CTE’s) to solve this
DATE(s) – Practice 1
61. 1. What is the Average number of Years spent by employees on each Role?
2. In order to calculate this information we will need to use HumanResources.Employee table
3. Calculate results for TOP 20 and TOP 20% of such products
Note: It would wise to break the problem down into different parts and use WITH (CTE’s) to
solve this
DATE(s) – Practice 2
Editor's Notes
CREATE TABLE Sales.CallLog
(CallID int IDENTITY PRIMARY KEY NOT NULL,
CallTime datetime NOT NULL DEFAULT GETDATE(),
SalesPerson nvarchar(256) NOT NULL,
CustomerID int NOT NULL,
PhoneNumber nvarchar(25) NOT NULL,
Notes nvarchar(max) NULL
);
INSERT INTO Sales.CallLog
VALUES
('2015-01-01T01:30:00', 'adventure-works\james’, 2, '245-555-0173', 'Returning call re: Acknowledging delivery');
INSERT INTO Sales.CallLog
VALUES
(' ', 'adventure-works\Wilfred’, 6, '245-654-0298', 'Report: Store closure confirmation');
INSERT INTO Sales.CallLog
VALUES
('2015-01-01T01:45:00', 'adventure-works\Abdullah’,7, '245-654-0298', 'Report: Theft at store');
INSERT INTO Sales.CallLog
VALUES
('2015-01-01T01:45:00', 'adventure-works\Abdullah', 345, '245-654-0298', 'Report: Theft at store');
INSERT INTO Sales.CallLog
VALUES
('2015-01-01T12:30:00', 'adventure-works\pamela0', 1, '245-555-0173', ‘Returning call re: Acknowledging delivery');
DELETE SALES.CallLog
WHERE CallID = 6;
DELETE SALES.CallLog
WHERE CallID = 7;
DELETE SALES.CallLog
WHERE CustomerID = 1;
UPDATE Sales.CallLog
set SalesPerson = 'adventure-works\Jamie'
WHERE CallID =2
UPDATE Sales.CallLog
set SalesPerson = 'adventure-works\Alex',
PhoneNumber = '245-000-999',
Notes = 'Report: Shipment delivery'
WHERE CallID =2;
ALTER TABLE Sales.CallLog
ADD Address nvarchar(256);
UPDATE Sales.CallLog
SET Address = 'House # 60, Street 5, ABC Drive'
WHERE CallID = 1 ;
ALTER TABLE Sales.CallLog
DROP COLUMN Address;
ALTER TABLE Sales.CallLog
ADD CALLER_GENDER nvarchar(256);
UPDATE Sales.CallLog
SET CALLER_GENDER = 'M'
WHERE CallID = 1
UPDATE Sales.CallLog
SET CALLER_GENDER = 'M'
WHERE CallID = 2
UPDATE Sales.CallLog
SET CALLER_GENDER = 'M'
WHERE CallID = 4
UPDATE Sales.CallLog
SET CALLER_GENDER = 'M'
WHERE CallID = 7
UPDATE Sales.CallLog
SET CALLER_GENDER = 'F'
WHERE CallID IN (3,5,6)
P1
SELECT ProductDescriptionID, Description, ModifiedDate
FROM Production.ProductDescription;
P1
SELECT *
FROM Sales.SpecialOffer WHERE DiscountPct <= 0.2 AND
Category = 'Reseller' AND
type = 'Seasonal Discount’;
P2
SELECT *
FROM Production.TransactionHistory
WHERE ReferenceOrderID >=5000 OR
TransactionID <=100200;
P3
SELECT *
FROM Sales.Store
WHERE BusinessEntityID >=312 OR
Name = 'Areas Bike Accessories';
P1
P2
P3
P1
SELECT *
FROM Purchasing.Vendor
WHERE Name LIKE (‘A%');
P2
SELECT *
FROM Purchasing.Vendor
WHERE Name LIKE (‘A%');
P3
SELECT *
FROM Purchasing.Vendor
WHERE Name NOT LIKE (‘%ng%’);
P4
SELECT *
FROM Purchasing.Vendor
WHERE Name LIKE (‘__r%’);
P5
SELECT *
FROM Purchasing.Vendor
WHERE Name NOT LIKE (‘g%y');
P1
SELECT * FROM Person.EmailAddress
WHERE BusinessEntityID BETWEEN 30 AND 50 ;
P2
SELECT * FROM Person.EmailAddress
WHERE BusinessEntityID IN (30,35,36,37,45,48,70) ;
P1
SELECT SUM(Quantity)
FROM Production.TransactionHistory
WHERE TransactionType = 'S’;
P2
SELECT COUNT(Quantity)
FROM Production.TransactionHistory
WHERE TransactionType = 'W’;
P3
SELECT *
FROM Purchasing.Vendor
WHERE Name NOT LIKE (‘%ng%’);
P4
SELECT *
FROM Purchasing.Vendor
WHERE Name LIKE (‘__r%’);
P5
SELECT *
FROM Purchasing.Vendor
WHERE Name NOT LIKE (‘g%y');
P1
SELECT AVG(LineTotal) AS AVGLineTotal
FROM Sales.SalesOrderDetail
WHERE LineTotal <=3000 ;
P2
SELECT AVG(LineTotal) AS AVGLineTotal,
MIN(LineTotal) AS MINLineTotal,
MAX(LineTotal) AS MAXLineTotal
FROM Sales.SalesOrderDetail
WHERE ProductID BETWEEN 700 AND 800
P3
SELECT AVG(LineTotal) AS AVGLineTotal,
MIN(LineTotal) AS MINLineTotal,
MAX(LineTotal) AS MAXLineTotal
FROM Sales.SalesOrderDetail
WHERE ProductID BETWEEN 700 AND 800
AND SpecialOfferID = 2;
P1
SELECT SpecialOfferID,
SUM(UnitPrice) AS SUMUnitPrice,
AVG(UnitPrice) AS AVGUnitPrice
FROM Sales.SalesOrderDetail
GROUP BY SpecialOfferID;
P2
SELECT SpecialOfferID,
SUM(UnitPrice) AS SUMUnitPrice,
AVG(UnitPrice) AS AVGUnitPrice,
AVG(UnitPriceDiscount) AS AVGUnitPriceDiscount
FROM Sales.SalesOrderDetail
GROUP BY SpecialOfferID;
P3
SELECT
CardType,
AVG(ExpMonth) AS AVGExpMonth
FROM Sales.CreditCard
GROUP BY CardType;
P3+Individual Validation
Select SUM(ExpMonth), COUNT(*)
FROM Sales.CreditCard
Where CardType LIKE 'Sup%';
Example 1
SELECT
ProductId, AVG(LineTotal) AS AVGLineTotal,
MIN(LineTotal) AS MINLineTotal, MAX(LineTotal) AS MAXLineTotal
FROM Sales.SalesOrderDetail GROUP BY ProductId
HAVING AVG(LineTotal) > 2000;
P1
SELECT
SalesOrderID,
SUM(LineTotal) AS SUMLineTotal
FROM Sales.SalesOrderDetail
GROUP BY SalesOrderID
HAVING SUM(LineTotal) BETWEEN 599 AND 3000 ;
P2
SELECT
SalesOrderID,
SUM(LineTotal) AS SUMLineTotal
FROM Sales.SalesOrderDetail
GROUP BY SalesOrderID
HAVING SUM(LineTotal) <=789;
P3
SELECT
WorkOrderID,
SUM(OrderQty) AS SUMOrderQty,
SUM(StockedQty) AS SUMStockedQty
FROM Production.WorkOrder
GROUP BY WorkOrderID
HAVING SUM(OrderQty) >10 AND
SUM(StockedQty) < 15;
Reuse Example:
SELECT
WorkOrderID,
SUM(OrderQty) AS SUMOrderQty,
SUM(StockedQty) AS SUMStockedQty
FROM Production.WorkOrder
GROUP BY WorkOrderID
HAVING SUM(OrderQty) >10 AND
SUM(StockedQty) < 15
ORDER BY WorkOrderID DESC;
P1
SELECT *
FROM person.Address
SELECT *
FROM person.StateProvince;
SELECT
Address.AddressLine1,
Address.AddressLine2,
COUNT(StateProvince.Name)
FROM person.Address
LEFT JOIN person.StateProvince ON
Address.StateProvinceID = StateProvince.StateProvinceID
GROUP BY AddressLine1, AddressLIne2;
https://www.youtube.com/watch?v=lYKkro6rKm0
Hypothetical DB – FULL OUTER JOIN
SELECT EmployeeDemographics.*, WareHouseEmployeeDemographics.*
FROM EmployeeDemographics
FULL OUTER JOIN WareHouseEmployeeDemographics ON
EmployeeDemographics.EmployeeID = WareHouseEmployeeDemographics.EmployeeID
UNION
SELECT *
FROM Sales.Customer
UNION
SELECT *
FROM Sales.Customer
ORDER BY CustomerID;
UNION ALL
SELECT *
FROM Sales.Customer
UNION ALL
SELECT *
FROM Sales.Customer
ORDER BY CustomerID;
https://www.youtube.com/watch?v=lYKkro6rKm0
Hypothetical DB – FULL OUTER JOIN
SELECT EmployeeDemographics.*, WareHouseEmployeeDemographics.*
FROM EmployeeDemographics
FULL OUTER JOIN WareHouseEmployeeDemographics ON
EmployeeDemographics.EmployeeID = WareHouseEmployeeDemographics.EmployeeID
UNION
Select *
FROM dbo.EmployeeDemographics
UNION
SELECT *
FROM dbo.WareHouseEmployeeDemographics;
UNION ALL
Select *
FROM dbo.EmployeeDemographics
UNION ALL
SELECT *
FROM dbo.WareHouseEmployeeDemographics;
P1:
SELECT Top 30
PP.Name,
SUM(SOD.OrderQty) AS OrderQty,
SUM(SOD.UnitPrice) AS UnitPrice ,
SUM(SOD.LineTotal) AS LineTotal
FROM Sales.SalesOrderDetail AS SOD
LEFT JOIN Production.Product AS PP ON
SOD.ProductID = PP.ProductID
GROUP BY PP.Name
ORDER BY LineTotal DESC;
P2:
SELECT Top 15 PERCENT
PP.Name,
SUM(SOD.OrderQty) AS OrderQty,
SUM(SOD.UnitPrice) AS UnitPrice ,
SUM(SOD.LineTotal) AS LineTotal
FROM Sales.SalesOrderDetail AS SOD
INNER JOIN Production.Product AS PP ON
SOD.ProductID = PP.ProductID
GROUP BY PP.Name
ORDER BY LineTotal DESC;
P3:
SELECT Top 10 PERCENT
PS.Name AS ProductSubcategory,
PP.Name,
SUM(SOD.OrderQty) AS OrderQty,
SUM(SOD.UnitPrice) AS UnitPrice ,
SUM(SOD.LineTotal) AS LineTotal
FROM Sales.SalesOrderDetail AS SOD
INNER JOIN Production.Product AS PP ON
SOD.ProductID = PP.ProductID
INNER JOIN Production.ProductSubcategory AS PS ON
PP.ProductSubcategoryID = PS.ProductSubcategoryID
GROUP BY PS.Name, PP.Name
ORDER BY LineTotal DESC;
E1:
SELECT *,
CAST(AverageRate AS int),
CAST(CurrencyRateDate AS date),
CAST(CurrencyRateDate AS time),
CAST(CurrencyRateDate AS int)
FROM Sales.CurrencyRate;
Example 1:
Original
SELECT
PR.Name,
SOD.ProductID AS ProductID,
CAST(SUM(LineTotal) AS INT) AS LineTotal
FROM Sales.SalesOrderDetail AS SOD
INNER JOIN Production.Product AS PR ON
SOD.ProductID = PR.ProductID
GROUP BY PR.Name, SOD.ProductID
FINAL
SELECT
PR.Name,
SOD.ProductID AS ProductID,
CAST(SUM(LineTotal) AS INT) AS LineTotal,
CASE WHEN SUM(LineTotal) <5000 THEN 'Poor Performance'
WHEN SUM(LineTotal) < 15000 THEN 'Average Performance'
ELSE 'Great Performance' END AS Categories
FROM Sales.SalesOrderDetail AS SOD
INNER JOIN Production.Product AS PR ON
SOD.ProductID = PR.ProductID
GROUP BY PR.Name, SOD.ProductID
P1:
SELECT PersonID,
TerritoryID,
CASE WHEN PersonID IS NULL THEN TerritoryID
ELSE PersonID END AS Test
FROM Sales.Customer;
P1:
SELECT *
FROM( SELECT
ProductID,
(UnitPrice * OrderQty) AS NewLineTotal
FROM Sales.SalesOrderDetail) AS Subquery
WHERE NewLineTotal > 20000;
P1 Trying with an Aggregator in the WHERE clause:
SELECT *
FROM(
SELECT *
FROM Production.TransactionHistory
WHERE ActualCost <> 0 AND
TransactionType IN ('P','S')) AS Subquery
WHERE ActualCost > AVG(ActualCost);
P2:
SELECT *
FROM(
SELECT *
FROM Production.TransactionHistory
WHERE ActualCost <> 0 AND
TransactionType IN ('P','S')) AS Subquery1
WHERE ActualCost > 2000;
P1:
First lets find the Average Value
SELECT
AVG(LineTotal)
FROM Sales.SalesOrderDetail;
Then lets place the first query inside a where clause.
SELECT *
FROM Sales.SalesOrderDetail
WHERE LineTotal >
(SELECT
AVG(LineTotal)
FROM Sales.SalesOrderDetail)
ORDER BY LineTotal;
P2:
First lets find the Average Value
SELECT
AVG(SalesYTD) as Avg
FROM Sales.SalesPerson
Then lets place the first query inside a where clause.
SELECT *
FROM Sales.SalesPerson
WHERE SalesYTD >
(SELECT
AVG(SalesYTD) as Avg
FROM Sales.SalesPerson);
P3:
First lets find the Average Value of the difference
SELECT
AVG(SalesYTD - SalesLastYear) AS AVGDIfference
FROM Sales.SalesPerson
Then lets place the first query inside a where clause.
SELECT
(SalesYTD - SalesLastYear) As Diff
FROM Sales.SalesPerson
WHERE (SalesYTD - SalesLastYear) < (
SELECT
AVG(SalesYTD - SalesLastYear) AS AVGDIfference
FROM Sales.SalesPerson);
P4 Extra (Not on the slide): This is an example of finding anti sets between two tables
SELECT *
FROM Production.Product
WHERE ProductID NOT IN (
SELECT ProductID
FROM Sales.SalesOrderDetail
WHERE Product.ProductID = SalesOrderDetail.ProductID)
P1:
SELECT
SalesOrderID,
UnitPrice,
LineTotal,
(Select AVG(LineTotal) FROM Sales.SalesOrderDetail) AS AVGLineTotal,
(LineTotal - (Select AVG(LineTotal) FROM Sales.SalesOrderDetail)) AS Difference
FROM Sales.SalesOrderDetail;
UseCase1:
SELECT *
FROM Sales.SalesOrderDetail
WHERE LineTotal < ALL (
SELECT ListPrice
FROM Production.Product
) ORDER BY LineTotal;
UseCase2: Remember to go step by step)
SELECT *
FROM Sales.SalesOrderDetail;
SELECT *
FROM Sales.SpecialOffer;
For Overall Search
SELECT
SalesOrderID,
SpecialOfferID,
SUM(OrderQty) AS OrderQty,
UnitPriceDiscount
FROM Sales.SalesOrderDetail
GROUP BY SalesOrderID, SpecialOfferID, UnitPriceDiscount
HAVING SUM(OrderQty) < ALL (
SELECT MinQty
FROM Sales.SpecialOffer
WHERE MinQty <> 0 OR
DiscountPct <> 0.00);
For Specific Search
SELECT
SalesOrderID,
SpecialOfferID,
SUM(OrderQty) AS OrderQty,
UnitPriceDiscount
FROM Sales.SalesOrderDetail
WHERE SpecialOfferID = 2 AND UnitPriceDiscount <> 0
GROUP BY SalesOrderID, SpecialOfferID, UnitPriceDiscount
HAVING SUM(OrderQty) < ALL (
SELECT MaxQty
FROM Sales.SpecialOffer
WHERE SpecialOfferID = 2);
UseCase 1:
WITH test(AvgLineTotal) AS
(
SELECT AVG(LineTotal)
FROM Sales.SalesOrderdetail
WHERE SpecialOfferID =2)
SELECT
SalesOrderID,
ProductID,
SalesOrderDetailID,
OrderQty,
UnitPrice,
LineTotal
FROM Sales.SalesOrderDetail, test
WHERE LineTotal > test.AvgLineTotal
ORDER BY LineTotal;
UseCase2:
WITH prodtable(ProductID,Name,ProductNumber) AS (
SELECT
Product.ProductID,
Product.Name,
Product.ProductNumber
FROM Production.Product
WHERE Product.Name LIKE 'B%'),
Salestable(SalesOrderID, ProductID, UnitPrice,LineTotal) AS
(SELECT
SalesOrderID,
ProductID,
UnitPrice,
LineTotal
FROM Sales.SalesOrderDetail)
SELECT
prodtable.*,
Salestable.*
From Salestable
INNER JOIN prodtable ON
Salestable.ProductID = prodtable.ProductID;
P1
WITH Sales(AvgOrderQty) AS
(
SELECT
AVG(OrderQty)
FROM Sales.SalesOrderDetail
GROUP BY SpecialOfferID
HAVING SpecialOfferID = 14)
SELECT *
FROM Sales.SalesOrderDetail,Sales
WHERE OrderQty > Sales.AvgOrderQty
ORDER BY OrderQty;
P2
WITH Sales(AvgOrderQty) AS
(
SELECT
AVG(OrderQty)
FROM Sales.SalesOrderDetail
GROUP BY SpecialOfferID
HAVING SpecialOfferID = 14 ),
Sales1(SalesOrderDetailID,SpecialOfferID,OrderQty,LineTotal) AS
(
SELECT
SalesOrderDetailID,
SpecialOfferID,
OrderQty,
LineTotal
FROM Sales.SalesOrderDetail,Sales
WHERE OrderQty > Sales.AvgOrderQty)
SELECT
Sales1.*,
SpecialOffer.Type,
SpecialOffer.Category,
DiscountPct
From Sales1
INNER JOIN Sales.SpecialOffer ON
Sales1.SpecialOfferID = SpecialOffer.SpecialOfferID
Order BY OrderQty;
Date Functions 1 By 1
SELECT ModifiedDate,
GETDATE() as Today, ---Gets todays date---
MONTH(ModifiedDate), ---Extracts the Month Number---
DAY(ModifiedDate), ---Extracts Day of the Month---
YEAR(ModifiedDate), ---Extracts the Year from a date---
DATEDIFF(MONTH,ModifiedDate,GETDATE()), ---Calculated Difference between two dates---
DATEADD(Year,30,GETDATE()), ---Added an year to current year---
DATEFROMPARTS(2018,1,31), ---Insert Date with control over the format(Year, Month, Date)---
DATENAME(Day,GETDATE()), ---Returns a Date/Year/Month/Day as a String Value---
DATEPART(Day,GETDATE()), ---Returns a Date/Year/Month/Day as an Integer---
GETUTCDATE(), ---Returns a Coordinated Universal Time (UTC)---
ISDATE(ModifiedDate), ---Checks whether a Date is a Date Type or not, Returns 1 if true and 0 if False---
ISDATE(DATENAME(Day,GETDATE())) ---Checks whether a Date is a Date Type or not, Returns 1 if true and 0 if False---
FROM Person.Person;
P1 Solution
WITH CTE AS (
SELECT *,
DAY(ScheduledEndDate - ScheduledStartDate) AS Scheduled,
DAY(ActualEndDate - ActualStartDate) AS Actual,
DAY(ActualEndDate - ActualStartDate) - DAY(ScheduledEndDate - ScheduledStartDate) AS DIFF
FROM Production.WorkOrderRouting),
CTE1 AS(
SELECT
ProductID,
SUM(Scheduled) AS Scheduled,
SUM(Actual) AS Actual,
SUM(Actual) - SUM(Scheduled) AS DIFF
FROM CTE
GROUP BY ProductID)
SELECT TOP 20
CTE1.ProductID,
PP.Name,
Scheduled,
Actual,
DIFF
FROM CTE1
LEFT JOIN Production.Product AS PP ON
CTE1.ProductID = PP.ProductID
ORDER BY DIFF DESC;
P2 Solution
WITH CTE AS (
SELECT
JobTitle,
YEAR(CAST(HireDate AS datetime)) as HireDate,
YEAR(CAST(GETDATE() AS datetime)) AS Today
FROM HumanResources.Employee),
CTE1 AS(
SELECT
JobTitle,
Today - HireDate AS DIFF
FROM CTE
GROUP BY JobTitle, Today, HireDate)
SELECT
JobTitle,
AVG(DIFF) AS DIFF
FROM CTE1
GROUP BY JobTitle
ORDER BY DIFF DESC;
Solution 1 (ROLL UP)SELECT
SOD.SalesOrderID,
P.Name,
SUM(SOD.LineTotal) AS LineTotal
FROM Sales.SalesOrderDetail AS SOD
INNER JOIN Production.Product AS P
ON SOD.ProductID = P.ProductID
GROUP BY ROLLUP (SOD.SalesOrderID, P.Name)
ORDER BY SOD.SalesOrderID DESC;
Solution 1.1 (Showing filtered ‘Mountain Bike Socks’)
SELECT
P.Name,
SOD.SalesOrderID,
SUM(SOD.UnitPrice)
FROM Sales.SalesOrderDetail AS SOD
INNER JOIN Production.Product as P
ON SOD.ProductID = P.ProductID
GROUP BY ROLLUP (P.Name,SalesOrderID)
HAVING P.Name LIKE 'Mountain Bike Socks%';
Solution 1 (ROLL UP, SOD & P.Name)SELECT
SOD.SalesOrderID,
P.Name,
SUM(SOD.LineTotal) AS LineTotal
FROM Sales.SalesOrderDetail AS SOD
INNER JOIN Production.Product AS P
ON SOD.ProductID = P.ProductID
GROUP BY ROLLUP (SOD.SalesOrderID, P.Name)
ORDER BY SOD.SalesOrderID DESC;
Solution 1 (ROLL UP, P.Name & SOD)
SELECT
SOD.SalesOrderID,
P.Name,
SUM(SOD.LineTotal) AS LineTotal
FROM Sales.SalesOrderDetail AS SOD
INNER JOIN Production.Product AS P
ON SOD.ProductID = P.ProductID
GROUP BY ROLLUP (P.Name,SOD.SalesOrderID)
ORDER BY SOD.SalesOrderID DESC;
Solution 1 (CUBE)
SELECT
SOD.SalesOrderID,
P.Name,
SUM(SOD.LineTotal) AS LineTotal
FROM Sales.SalesOrderDetail AS SOD
INNER JOIN Production.Product AS P
ON SOD.ProductID = P.ProductID
GROUP BY CUBE (SOD.SalesOrderID, P.Name)
ORDER BY SOD.SalesOrderID DESC;
Solution 1 (GROUPING SETS)SELECT
SOD.SalesOrderID,
P.Name,
SUM(SOD.LineTotal) AS LineTotal
FROM Sales.SalesOrderDetail AS SOD
INNER JOIN Production.Product AS P
ON SOD.ProductID = P.ProductID
GROUP BY GROUPING SETS ((SOD.SalesOrderID, P.Name),SOD.SalesOrderID, P.name,())
ORDER BY SOD.SalesOrderID DESC;