Continuing with Microsoft’s T-SQL certificate, here I’m grouping sets and using the PIVOT operator to summarize data.
Lab 8
1. include a grand total for all sales revenue and a subtotal for each country/region in addition to the state/province subtotals that are already returned. Make sure to use the aliases provided, and default column names elsewhere.
SELECT a.CountryRegion, a.StateProvince, SUM(soh.TotalDue) AS Revenue
FROM SalesLT.Address AS a
JOIN SalesLT.CustomerAddress AS ca
ON a.AddressID = ca.AddressID
JOIN SalesLT.Customer AS c
ON ca.CustomerID = c.CustomerID
JOIN SalesLT.SalesOrderHeader as soh
ON c.CustomerID = soh.CustomerID
-- Modify GROUP BY to use ROLLUP
GROUP BY ROLLUP(a.CountryRegion, a.StateProvince)
ORDER BY a.CountryRegion, a.StateProvince;
- ROLLUP: generates a result set that shows aggregates for a hierarchy of values in the selected columns.
- CUBE: generates a result set that shows aggregates for all combinations of values in the selected columns.
2. Modify your query to include a column named Level
that indicates at which level in the total, country/region, and state/province hierarchy the revenue figure in the row is aggregated.
For example, the grand total row should contain the value ‘Total’, the row showing the subtotal for United States should contain the value ‘United States Subtotal’, and the row showing the subtotal for California should contain the value ‘California Subtotal’.
SELECT a.CountryRegion, a.StateProvince,
IIF(GROUPING_ID(a.CountryRegion) = 1 AND GROUPING_ID(a.StateProvince) = 1, 'Total', IIF(GROUPING_ID(a.StateProvince) = 1, a.CountryRegion + ' Subtotal', a.StateProvince + ' Subtotal')) AS Level,
SUM(soh.TotalDue) AS Revenue
FROM SalesLT.Address AS a
JOIN SalesLT.CustomerAddress AS ca
ON a.AddressID = ca.AddressID
JOIN SalesLT.Customer AS c
ON ca.CustomerID = c.CustomerID
JOIN SalesLT.SalesOrderHeader as soh
ON c.CustomerID = soh.CustomerID
GROUP BY ROLLUP(a.CountryRegion, a.StateProvince)
ORDER BY a.CountryRegion, a.StateProvince;
3. Extend your query to include a grouping for individual cities. Make sure to use the aliases provided, and default column names elsewhere.
SELECT a.CountryRegion, a.StateProvince, a.City,
CHOOSE (1 + GROUPING_ID(a.CountryRegion) + GROUPING_ID(a.StateProvince) + GROUPING_ID(a.City),
a.City + ' Subtotal', a.StateProvince + ' Subtotal',
a.CountryRegion + ' Subtotal', 'Total') AS Level,
SUM(soh.TotalDue) AS Revenue
FROM SalesLT.Address AS a
JOIN SalesLT.CustomerAddress AS ca
ON a.AddressID = ca.AddressID
JOIN SalesLT.Customer AS c
ON ca.CustomerID = c.CustomerID
JOIN SalesLT.SalesOrderHeader as soh
ON c.CustomerID = soh.CustomerID
GROUP BY ROLLUP(a.CountryRegion, a.StateProvince, a.City)
ORDER BY a.CountryRegion, a.StateProvince, a.City;
- CHOOSE: The following example returns the third item from the list of values that is provided.
- SELECT CHOOSE ( 3, ‘Manager’, ‘Director’, ‘Developer’, ‘Tester’ ) AS Result;
- Result: Developer
4. Retrieve a list of customer company names together with their total revenue for each parent category in Accessories
, Bikes
, Clothing
, and Components
. Make sure to use the aliases provided, and default column names elsewhere.
SELECT * FROM
(SELECT cat.ParentProductCategoryName, cust.CompanyName, sod.LineTotal
FROM SalesLT.SalesOrderDetail AS sod
JOIN SalesLT.SalesOrderHeader AS soh
ON sod.SalesOrderID = soh.SalesOrderID
JOIN SalesLT.Customer AS cust
ON soh.CustomerID = cust.CustomerID
JOIN SalesLT.Product AS prod
ON sod.ProductID = prod.ProductID
JOIN SalesLT.vGetAllCategories AS cat
ON prod.ProductcategoryID = cat.ProductCategoryID) AS Sales
PIVOT (SUM(LineTotal) FOR ParentProductCategoryName IN([Accessories],[Bikes],[Clothing],[Components])
) AS pvt;
- PIVOT & UNPIVOT: PIVOT rotates a table-valued expression by turning the unique values from one column in the expression into multiple columns in the output, and performs aggregations where they are required on any remaining column values that are wanted in the final output. UNPIVOT performs the opposite operation to PIVOT by rotating columns of a table-valued expression into column values.
Lab 9
Inserting Products
1. Each AdventureWorks product is stored in the SalesLT.Product
table, and each product has a unique ProductID
identifier, which is implemented as an IDENTITY
column in the SalesLT.Product
table.
Products are organized into categories, which are defined in the SalesLT.ProductCategory
table.
The products and product category records are related by a common ProductCategoryID
identifier, which is an IDENTITY
column in the SalesLT.ProductCategory
table.
The new product to be inserted is shown in this table:
AdventureWorks has started selling the new product shown in the table above. Insert it into the SalesLT.Product
table, using default or NULL
values for unspecified columns. Once you’ve inserted the product, run SELECT SCOPE_IDENTITY();
to get the last identity value that was inserted. Add a query to view the row for the product in the SalesLT.Product
table.
— INSERT statement
INSERT INTO SalesLT.Product (Name, ProductNumber, StandardCost, ListPrice, ProductCategoryID, SellStartDate)
VALUES
('LED Lights', 'LT-L123', 2.56, 12.99, 37, GETDATE());
— Get last identity value that was inserted
SELECT SCOPE_IDENTITY();
— SELECT statement
SELECT * FROM SalesLT.Product
WHERE ProductID = SCOPE_IDENTITY();
2. Write a query to insert this new product category into the SalesLT.ProductCategory
table. Insert the ParentProductCategoryID
, followed by the Name
of the new product.
— Insert a product category
INSERT INTO SalesLT.ProductCategory (ParentProductCategoryID, Name)
VALUES
(4, 'Bells and Horns');
3. Insert the two new products with the appropriate ProductCategoryID
value, based on the product details above. Join the SalesLT.Product
and SalesLT.ProductCategory
tables. That way, you can verify that the data has been inserted. Make sure to use the aliases provided, and default column names elsewhere.
— Insert product category
INSERT INTO SalesLT.ProductCategory (ParentProductCategoryID, Name)
VALUES
(4, 'Bells and Horns');
— Insert 2 products
INSERT INTO SalesLT.Product (Name, ProductNumber, StandardCost, ListPrice, ProductCategoryID, SellStartDate)
VALUES
('Bicycle Bell', 'BB-RING', 2.47, 4.99, IDENT_CURRENT('SalesLT.ProductCategory'), GETDATE()),
('Bicycle Horn', 'BB-PARP', 1.29, 3.75, IDENT_CURRENT('SalesLT.ProductCategory'), GETDATE());
— Check if products are properly inserted
SELECT c.Name As Category, p.Name AS Product
FROM SalesLT.Product AS p
JOIN SalesLT.ProductCategory as c ON p.ProductCategoryID = c.ProductCategoryID
WHERE p.ProductCategoryID = IDENT_CURRENT('SalesLT.ProductCategory');
Updating Products
4. The sales manager at AdventureWorks has mandated a 10% price increase for all products in the Bells and Horns category. Update the rows in the SalesLT.Product
table for these products to increase their price by 10%.
— Update the SalesLT.Product table–
UPDATE SalesLT.Product
SET ListPrice = ListPrice * 1.1
WHERE ProductCategoryID = (SELECT ProductCategoryID FROM SalesLT.ProductCategory WHERE Name = 'Bells and Horns');
5. Set the DiscontinuedDate
to today’s date for all products in the Lights category (ProductCategoryID
37) other than the LED Lights product you inserted previously.
— UPDATE query
UPDATE SalesLT.Product
SET DiscontinuedDate = GETDATE()
WHERE ProductCategoryID = 37
AND ProductNumber <> 'LT-L123';
Deleting Products
6. Delete the records for the Bells and Horns category and its products. You must ensure that you delete the records from the tables in the correct order to avoid a foreign-key constraint violation.
— Delete records from the SalesLT.Product table–
DELETE FROM SalesLT.Product
WHERE ProductCategoryID = (SELECT ProductCategoryID FROM SalesLT.ProductCategory WHERE Name = 'Bells and Horns');
— Delete records from the SalesLT.ProductCategory table
DELETE FROM SalesLT.ProductCategory
WHERE ProductCategoryID = (SELECT ProductCategoryID FROM SalesLT.ProductCategory WHERE Name = 'Bells and Horns');