├── Chapter05 ├── Exercise5.07.sql ├── Exercise5.05.sql ├── Exercise5.06.sql ├── Exercise5.04.sql ├── Exercise5.02.sql ├── Exercise5.03.sql ├── Exercise5.01.sql ├── Activity Sol ├── Needs to be deleted └── Chapter 5 Scripts.sql ├── Chapter02 ├── Exercise2.03.sql ├── Exercise2.05.SQL ├── Exercise2.04.SQL ├── Exercise2.01.sql ├── Exercise2.02.sql └── Activity ├── Chapter04 ├── Exercise4.01.sql ├── Exercise4.03.sql ├── Exercise4.04.sql ├── Exercise4.05.sql ├── Exercise4.02.sql ├── Activity Solution ├── Customers1.sql └── Chapter 4 ├── SCRIPTS ├── SQL SERVER SCRIPTS │ ├── SQL_SERVER_create_database_script.sql │ └── SQL_SERVER_create_data.sql └── MYSQL SCRIPTS │ ├── MYSQL_create_database_script.sql │ └── MySQL_create_data.sql ├── Chapter07 ├── Exercise7.01.sql ├── Exercise7.02.sql ├── Exercise7.03.sql └── Chapter 7 Activity.sql ├── Chapter11 ├── Exercise11.01.sql ├── Exercise11.03.sql └── Exercise11.02.sql ├── Chapter06 ├── Exercise 6.01.sql ├── Exercise6.05.sql ├── Activity Sol ├── Exercise6.03.sql ├── Exercise6.02.sql ├── Exercise6.04.sql └── Chapter 6 Scripts.sql ├── Chapter09 ├── Exercise9.02.sql └── Chapter 9 Scripts.sql ├── Chapter01 ├── Exercise1.01.sql ├── Exercise 1.02.csv ├── Activity Sol └── Activity 1.01.csv ├── Chapter10 ├── Exercise10.02.sql ├── Exercise10.01.sql ├── Exercise10.03.sql ├── Example01.sql └── Chapter 10 Activity.sql ├── Chapter03 ├── Activity3.01 ├── Exercise3.01.sql └── Chapter 3 ├── LICENSE ├── Chapter08 ├── tr_Products_OnInsert └── tr_OrderItems_OnInsert.sql └── README.md /Chapter05/Exercise5.07.sql: -------------------------------------------------------------------------------- 1 | SELECT * 2 | FROM Customers 3 | WHERE FirstName = 'Joe' AND Phone LIKE '(310)%'; 4 | -------------------------------------------------------------------------------- /Chapter05/Exercise5.05.sql: -------------------------------------------------------------------------------- 1 | SELECT FirstName, LastName, Phone 2 | FROM Customers 3 | WHERE FirstName LIKE '___'; 4 | -------------------------------------------------------------------------------- /Chapter05/Exercise5.06.sql: -------------------------------------------------------------------------------- 1 | SELECT MiddleName, LastName, Phone 2 | FROM Customers 3 | WHERE FirstName IS NULL; 4 | -------------------------------------------------------------------------------- /Chapter02/Exercise2.03.sql: -------------------------------------------------------------------------------- 1 | USE PACKT_ONLINE_SHOP; 2 | DELETE FROM products 3 | WHERE ProductName = 'tomato sauce'; 4 | -------------------------------------------------------------------------------- /Chapter05/Exercise5.04.sql: -------------------------------------------------------------------------------- 1 | SELECT FirstName AS 'Customers from LA', Phone 2 | FROM Customers 3 | WHERE Phone LIKE '(310)%'; 4 | -------------------------------------------------------------------------------- /Chapter04/Exercise4.01.sql: -------------------------------------------------------------------------------- 1 | use PACKT_ONLINE_SHOP; 2 | SELECT ProductCategoryID, ProductCategoryName 3 | FROM ProductCategories; 4 | -------------------------------------------------------------------------------- /Chapter04/Exercise4.03.sql: -------------------------------------------------------------------------------- 1 | SELECT ProductName, NetRetailPrice 2 | FROM Products 3 | ORDER BY NetRetailPrice DESC 4 | LIMIT 5; 5 | -------------------------------------------------------------------------------- /Chapter04/Exercise4.04.sql: -------------------------------------------------------------------------------- 1 | SELECT ProductID, Quantity, UnitPrice, (Quantity*UnitPrice) AS 'Line Item Total' 2 | FROM OrderItems; 3 | -------------------------------------------------------------------------------- /Chapter02/Exercise2.05.SQL: -------------------------------------------------------------------------------- 1 | USE PACKT_ONLINE_SHOP; 2 | UPDATE products 3 | SET 4 | NetRetailPrice = NetRetailPrice * 0.90; 5 | -------------------------------------------------------------------------------- /Chapter05/Exercise5.02.sql: -------------------------------------------------------------------------------- 1 | SELECT ProductName,NetRetailPrice 2 | FROM Products 3 | WHERE NetRetailPrice BETWEEN 14.99 AND 50 4 | ORDER BY NetRetailPrice; 5 | -------------------------------------------------------------------------------- /SCRIPTS/SQL SERVER SCRIPTS/SQL_SERVER_create_database_script.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktWorkshops/The-SQL-Workshop/HEAD/SCRIPTS/SQL SERVER SCRIPTS/SQL_SERVER_create_database_script.sql -------------------------------------------------------------------------------- /Chapter07/Exercise7.01.sql: -------------------------------------------------------------------------------- 1 | USE packt_online_shop; 2 | 3 | SELECT O.OrderID 4 | FROM Orders O 5 | WHERE O.OrderID NOT IN (SELECT OrderID FROM ORDERITEMS) 6 | ORDER BY O.OrderID; 7 | -------------------------------------------------------------------------------- /Chapter04/Exercise4.05.sql: -------------------------------------------------------------------------------- 1 | SELECT ProductID, Quantity, UnitPrice, (Quantity*UnitPrice) AS 'Line Item Total', Discount, ((Quantity*UnitPrice)-(Quantity*Discount)) AS 'Price After Discount' 2 | FROM OrderItems; 3 | -------------------------------------------------------------------------------- /Chapter04/Exercise4.02.sql: -------------------------------------------------------------------------------- 1 | SELECT ProductCategoryName AS CATEGORY, ProductCategoryID AS ID 2 | FROM ProductCategories; 3 | SELECT ProductCategoryName AS 'PRODUCT CATEGORY', ProductCategoryID AS ID 4 | FROM ProductCategories; 5 | -------------------------------------------------------------------------------- /Chapter11/Exercise11.01.sql: -------------------------------------------------------------------------------- 1 | USE packt_online_shop; 2 | 3 | SELECT OrderID, LTRIM(RTRIM(CONCAT(CAST(Quantity AS CHAR), ' Ordered: ', UPPER(Notes)))) 4 | AS 'ITEM_QUANTITY_ORDERED_AND_NOTES' 5 | 6 | FROM OrderItems; 7 | -------------------------------------------------------------------------------- /Chapter06/Exercise 6.01.sql: -------------------------------------------------------------------------------- 1 | SELECT Orders.OrderNumber, Orders.OrderStatus, Orders.OrderDate, 2 | Customers.FirstName, Customers.LastName, Customers.Email 3 | FROM Orders JOIN Customers ON Orders.CustomerID = Customers.CustomerID; 4 | -------------------------------------------------------------------------------- /Chapter09/Exercise9.02.sql: -------------------------------------------------------------------------------- 1 | USE packt_online_shop; 2 | 3 | GRANT EXECUTE ON PROCEDURE packt_online_shop.spFilterProductsByNRP TO 'TEMP_ACCOUNT_1'; 4 | 5 | packt_online_shop.spFilterProductsByNRP 6 | 7 | SHOW GRANTS FOR TEMP_ACCOUNT_1; 8 | -------------------------------------------------------------------------------- /Chapter11/Exercise11.03.sql: -------------------------------------------------------------------------------- 1 | USE PACKT_ONLINE_SHOP; 2 | 3 | SELECT CONCAT(COALESCE(FirstName, ' '), ' ', 4 | COALESCE(MiddleName, 'SUBSTITUTE MIDDLE NAME'), ' ', 5 | COALESCE(LastName, ' ')) as 'CombinedName' 6 | 7 | FROM customers; 8 | -------------------------------------------------------------------------------- /Chapter05/Exercise5.03.sql: -------------------------------------------------------------------------------- 1 | SELECT ProductName,NetRetailPrice 2 | FROM Products 3 | WHERE ProductName != 'tomato sauce' 4 | ORDER BY NetRetailPrice; 5 | SELECT ProductName,NetRetailPrice 6 | FROM Products 7 | WHERE ProductName <> 'tomato sauce' 8 | ORDER BY NetRetailPrice; 9 | 10 | -------------------------------------------------------------------------------- /Chapter05/Exercise5.01.sql: -------------------------------------------------------------------------------- 1 | use PACKT_ONLINE_SHOP; 2 | SELECT ProductName AS 'High-value Products', NetRetailPrice 3 | FROM Products 4 | WHERE NetRetailPrice > 14.99 5 | USE PACKT_ONLINE_SHOP; 6 | SELECT ProductName AS 'High-value Products', NetRetailPrice 7 | FROM Products 8 | WHERE NetRetailPrice >= 14.99 9 | -------------------------------------------------------------------------------- /Chapter06/Exercise6.05.sql: -------------------------------------------------------------------------------- 1 | SELECT CONCAT(Customers.FirstName,' ',Customers.LastName) as 'FULL NAME', 2 | Customers.Phone AS 'Phone Number' 3 | FROM Customers 4 | UNION 5 | SELECT Suppliers.ContactPerson AS 'Full Name', 6 | Suppliers.PhoneNumber AS 'Phone Number' 7 | FROM Suppliers 8 | -------------------------------------------------------------------------------- /Chapter06/Activity Sol: -------------------------------------------------------------------------------- 1 | /* Activity 6.01: Implementing JOINS */ 2 | 3 | SELECT Orders.OrderNumber, 4 | OrderItems.UnitPrice, 5 | OrderItems.Quantity, 6 | Products.ProductName 7 | FROM Orders JOIN OrderItems ON Orders.OrderID = 8 | OrderItems.OrderID 9 | JOIN Products ON OrderItems.ProductID = Products.ProductID 10 | -------------------------------------------------------------------------------- /Chapter11/Exercise11.02.sql: -------------------------------------------------------------------------------- 1 | CREATE PROCEDURE spFilterCustomers 2 | (emailString VARCHAR(100)) 3 | SELECT C.CustomerID, C.FirstName, C.LastName, C.Address, 4 | C.Email, C.Phone, C.Notes, C.BalanceNotes 5 | FROM Customers C 6 | WHERE C.email LIKE CONCAT('%', emailString, '%'); 7 | CALL spFilterCustomers('.edu') 8 | -------------------------------------------------------------------------------- /Chapter01/Exercise1.01.sql: -------------------------------------------------------------------------------- 1 | 2 | 3 | create database PACKT_ONLINE_SHOP; 4 | use PACKT_ONLINE_SHOP; 5 | create table Customers 6 | ( 7 | FirstName varchar(50) , 8 | MiddleName varchar(50) , 9 | LastName varchar(50) , 10 | HomeAddress varchar(250) , 11 | Email varchar(200) , 12 | Phone varchar(50) , 13 | Notes varchar(250) 14 | ); 15 | -------------------------------------------------------------------------------- /Chapter02/Exercise2.04.SQL: -------------------------------------------------------------------------------- 1 | delete from department where departmentNo>2; 2 | insert into department(departmentname,departmentLoc) 3 | values('Sales','LV'); 4 | delete from department where departmentNo=5; 5 | ALTER TABLE department AUTO_INCREMENT = 3 ; 6 | insert into department(departmentname,departmentLoc) 7 | values('Sales','LV'); 8 | select * from department; 9 | -------------------------------------------------------------------------------- /Chapter10/Exercise10.02.sql: -------------------------------------------------------------------------------- 1 | SELECT PC.ProductCategoryName, 2 | SUM(P.AvailableQuantity) AS 'TOTAL COUNT OF ALL 3 | PRODUCTS IN PRODUCT CATEGORY' 4 | FROM Products P INNER JOIN ProductCategories PC ON 5 | P.ProductCategoryID = PC.ProductCategoryID 6 | GROUP BY PC.ProductCategoryName 7 | HAVING SUM(P.AvailableQuantity) > 250 8 | ORDER BY ProductCategoryName; 9 | -------------------------------------------------------------------------------- /Chapter02/Exercise2.01.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE EMPLOYEE; 2 | USE EMPLOYEE; 3 | CREATE TABLE department ( 4 | departmentNo INT PRIMARY KEY, 5 | departmentName VARCHAR(20) NOT NULL, 6 | departmentLoc VARCHAR(50) NOT NULL 7 | ); 8 | INSERT INTO department ( 9 | departmentNo, 10 | departmentName, 11 | departmentLoc 12 | ) 13 | VALUES ( 14 | 1, 15 | 'Engg', 16 | 'Texas' 17 | ); 18 | -------------------------------------------------------------------------------- /Chapter06/Exercise6.03.sql: -------------------------------------------------------------------------------- 1 | SELECT Orders.OrderNumber, 2 | Orders.OrderStatus, 3 | Payments.PaymentRef, 4 | Payments.PaymentType 5 | 6 | FROM Payments LEFT JOIN Orders ON Payments.OrderID = Orders.OrderID 7 | 8 | SELECT Orders.OrderNumber, 9 | Orders.OrderStatus, 10 | Payments.PaymentRef, 11 | Payments.PaymentType 12 | 13 | FROM Orders LEFT JOIN Payments ON Payments.OrderID = Orders.OrderID 14 | -------------------------------------------------------------------------------- /Chapter10/Exercise10.01.sql: -------------------------------------------------------------------------------- 1 | SELECT O.OrderID, C.LastName, 2 | MIN(OI.UnitPrice) AS 'PRICE OF LOWEST PRICED PRODUCT OF 3 | THE ORDER', 4 | MAX(OI.UnitPrice) AS 'PRICE OF HIGHEST PRICED PRODUCT 5 | OF THE ORDER' 6 | FROM Customers C INNER JOIN Orders O ON 7 | C.CustomerID = O.CustomerID 8 | INNER JOIN OrderItems OI ON 9 | O.OrderID = OI.OrderID 10 | GROUP BY C.LastName, O.OrderID; 11 | -------------------------------------------------------------------------------- /Chapter05/Activity Sol: -------------------------------------------------------------------------------- 1 | /* Activity 5.01: Combining Conditions to Extract Store Data */ 2 | SELECT 3 | ProductName as [Product Name], 4 | NetRetailPrice as [Product Retail Price], 5 | AvailableQuantity as [Available Quantity] 6 | NetRetailPrice * AvailableQuantity as 'Total Price of Available Quantity 7 | From Products 8 | WHERE NetRetailPrice <= 24.99 9 | AND AvailableQuantity >=38 10 | AND NOT ProductName LIKE '10%'; 11 | 12 | -------------------------------------------------------------------------------- /Chapter06/Exercise6.02.sql: -------------------------------------------------------------------------------- 1 | SELECT Customers.FirstName, 2 | Customers.LastName, 3 | Customers.Email , 4 | Orders.OrderNumber, 5 | Orders.OrderStatus 6 | 7 | FROM Orders RIGHT JOIN Customers ON Orders.CustomerID = Customers.CustomerID 8 | 9 | SELECT Customers.FirstName, 10 | Customers.LastName, 11 | Customers.Email , 12 | Orders.OrderNumber, 13 | Orders.OrderStatus 14 | 15 | FROM Orders RIGHT JOIN Customers ON Orders.CustomerID = Customers.CustomerID 16 | WHERE Orders.OrderNumber IS NULL 17 | 18 | -------------------------------------------------------------------------------- /Chapter07/Exercise7.02.sql: -------------------------------------------------------------------------------- 1 | USE packt_online_shop; 2 | 3 | SELECT ProductName, NetRetailPrice, UnitKGWeight, 4 | CASE 5 | WHEN (NetRetailPrice * UnitKGWeight) <= 1.0 THEN 'Cheap' 6 | WHEN (NetRetailPrice * UnitKGWeight) > 1.0 AND(NetRetailPrice * 7 | UnitKGWeight) <= 35.00 THEN 'Mid-price' 8 | WHEN (NetRetailPrice * UnitKGWeight) > 35.00 AND 9 | (NetRetailPrice * UnitKGWeight) <= 100.00 THEN 'Expensive' 10 | ELSE 'Very Expensive' 11 | END AS 'Shipping Cost' 12 | FROM products; 13 | -------------------------------------------------------------------------------- /Chapter10/Exercise10.03.sql: -------------------------------------------------------------------------------- 1 | USE packt_online_shop; 2 | 3 | SELECT S.SupplierID, S.SupplierName, 4 | COUNT(P.ProductID) AS 'PRODUCT COUNT OF SUPPLIER', 5 | RANK () OVER ( 6 | ORDER BY COUNT(P.ProductID) DESC 7 | ) AS 'SUPPLIER RANK', 8 | DENSE_RANK () OVER ( 9 | ORDER BY COUNT(P.ProductID) DESC 10 | ) AS 'SUPPLIER DENSE_RANK' 11 | FROM Suppliers S INNER JOIN 12 | Products P ON S.SupplierID = P.SupplierID 13 | GROUP BY S.SupplierID, S.SupplierName; 14 | -------------------------------------------------------------------------------- /Chapter04/Activity Solution: -------------------------------------------------------------------------------- 1 | /* Activity 4.01: Displaying Particular Columns from the Table */ 2 | 3 | SELECT FirstName as [First Name], LastName as 4 | [Last Name], Phone as [Phone Number] 5 | FROM Customers 6 | 7 | /* Activity 4.02: Extracting the Top Five Highest Paid Items */ 8 | 9 | SELECT TOP 5 10 | Products.ProductName as [Product Name], 11 | Products.NetRetailPrice as [Product Retail Price], 12 | Products.AvailableQuantity as [Available Quantity], 13 | Products.AvailableQuantity * Products.NetRetailPrice as [Total Price of Available QTY] 14 | FROM Products 15 | 16 | ORDER BY Products.NetRetailPrice Desc 17 | -------------------------------------------------------------------------------- /Chapter06/Exercise6.04.sql: -------------------------------------------------------------------------------- 1 | Create table Facecards (cardvalue varchar (50)); 2 | insert into Facecards (cardvalue) values ('King'); 3 | insert into Facecards (cardvalue) values ('Queen'); 4 | insert into Facecards (cardvalue) values ('Jack'); 5 | insert into Facecards (cardvalue) values ('Ace'); 6 | 7 | Create table CardSuit (suit varchar(50)); 8 | insert into CardSuit (suit) values ('Heart'); 9 | insert into CardSuit (suit) values ('Spade'); 10 | insert into CardSuit (suit) values ('Clubs'); 11 | insert into CardSuit (suit) values ('Diamond'); 12 | 13 | SELECT Facecards.cardvalue, 14 | CardSuit.suit 15 | 16 | FROM Facecards CROSS JOIN CardSuit 17 | -------------------------------------------------------------------------------- /Chapter03/Activity3.01: -------------------------------------------------------------------------------- 1 | CREATE TABLE OrderItems 2 | ( 3 | OrderItemID INT NOT NULL AUTO_INCREMENT, 4 | OrderID INT NOT NULL, 5 | ProductID INT NOT NULL, 6 | Quantity INT NOT NULL, 7 | UnitPrice DECIMAL(10, 2) NOT NULL, 8 | Discount DECIMAL(10, 2) NULL, 9 | Notes VARCHAR(750) NULL, 10 | PRIMARY KEY (OrderItemID) 11 | ); 12 | CREATE TABLE Orders 13 | ( 14 | OrderID INT NOT NULL AUTO_INCREMENT, 15 | CustomerID INT NOT NULL, 16 | OrderNumber CHAR(50) NOT NULL, 17 | OrderDate DATETIME NOT NULL, 18 | ShipmentDate DATETIME NULL, 19 | OrderStatus CHAR(10) NULL, 20 | Notes VARCHAR(750) NULL, 21 | PRIMARY KEY (OrderID) 22 | ); 23 | ALTER TABLE OrderItems 24 | ADD FOREIGN KEY (OrderID) REFERENCES Orders(OrderID); 25 | -------------------------------------------------------------------------------- /Chapter01/Exercise 1.02.csv: -------------------------------------------------------------------------------- 1 | FirstName,MiddleName,LastName,HomeAddress,Email,Phone,Notes 2 | Joe,Greg,Smith,2356 Elm St.,joesmith@sfghwert.com,(310) 555-1212,Always gets products home delivered 3 | Grace,Murray,Hopper,123 Compilation Street,gmhopper@ftyuw46.com,(818) 555-3678,Compiler pioneer 4 | Ada,,Lovelace,22 Algorithm Way,adalovelace@fgjw54af.gov,(717) 555-3457,First software engineer 5 | Joseph,Force,Carter,1313 Mockingbird Lane,judgecrater@ev56gfwrty.com,(212) 555-5678,Works everyday 6 | Orville,,Wright,80 Bicycle Lane,owright@sdg98.edu,(211) 555-4444,First pilot 7 | Jacqueline,Jackie,Cochran,1701 Flightspeed Avenue,jackiecochrane@jryuwp8qe4w.gov,(717) 555-3457,Researcher 8 | ,Paul,Jones,126 Bonhomme Richard Ave,jpjones@bonhommerichard.edu,(216) 555-6232,Admiral -------------------------------------------------------------------------------- /Chapter03/Exercise3.01.sql: -------------------------------------------------------------------------------- 1 | DROP DATABASE IF EXISTS employeedemo; 2 | CREATE DATABASE employeedemo; 3 | USE employeedemo; 4 | 5 | CREATE TABLE department 6 | ( 7 | dno INT PRIMARY KEY, 8 | dname VARCHAR(30) UNIQUE NOT NULL, 9 | dlocation VARCHAR(30) UNIQUE NOT NULL 10 | ) 11 | CREATE TABLE employee 12 | ( 13 | eno CHAR(4) PRIMARY KEY, 14 | ename VARCHAR(30) NOT NULL, 15 | job VARCHAR(30) NOT NULL, 16 | manager CHAR(4), 17 | jdate TIMESTAMP NOT NULL, 18 | gender CHAR(1) CONSTRAINT gender_chk 19 | CHECK ( gender IN('M', 'F')), 20 | salary DECIMAL(8, 2) DEFAULT 0, 21 | comission DECIMAL(8, 2) DEFAULT 0, 22 | deptno INT NOT NULL, 23 | FOREIGN KEY (deptno) REFERENCES department(dno) 24 | ) 25 | 26 | -------------------------------------------------------------------------------- /Chapter02/Exercise2.02.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS department; 2 | CREATE TABLE department ( 3 | departmentNo INT PRIMARY KEY AUTO_INCREMENT, 4 | departmentName VARCHAR(20) NOT NULL, 5 | departmentLoc VARCHAR(50) DEFAULT 'NJ', 6 | departmentEstDate DATETIME DEFAULT NOW() 7 | ); 8 | INSERT INTO department ( 9 | departmentName 10 | ) 11 | VALUES ( 12 | 'MyDepartment' 13 | ); 14 | INSERT INTO department ( 15 | departmentName, 16 | departmentLoc) 17 | VALUES 18 | ( 19 | 'Administration', 20 | DEFAULT 21 | ), 22 | ( 23 | 'IT', 24 | DEFAULT 25 | ); 26 | INSERT INTO department ( 27 | departmentName, 28 | departmentLoc) 29 | VALUES 30 | ( 31 | 'Administration', 32 | 'NYC' 33 | ); 34 | -------------------------------------------------------------------------------- /Chapter07/Exercise7.03.sql: -------------------------------------------------------------------------------- 1 | USE PACKT_ONLINE_SHOP; 2 | CREATE VIEW PACKT_VIEW_1 3 | AS 4 | SELECT customers.CustomerID, orders.OrderDate, 5 | products.ProductID, products.ProductName, 6 | orderitems.Quantity * orderitems.UnitPrice AS 7 | 'PerProductSpending' 8 | FROM customers INNER JOIN orders ON 9 | customers.CustomerID = orders.CustomerID 10 | INNER JOIN orderitems ON 11 | orders.OrderID = orderitems.OrderID 12 | INNER JOIN products ON 13 | orderitems.ProductID = products.ProductID; 14 | 15 | 16 | USE PACKT_ONLINE_SHOP; 17 | 18 | SELECT CustomerID, OrderDate, ProductID, ProductName, 19 | PerProductSpending 20 | FROM PACKT_VIEW_1 21 | WHERE PerProductSpending > 14.99; 22 | -------------------------------------------------------------------------------- /Chapter10/Example01.sql: -------------------------------------------------------------------------------- 1 | USE PACKT_ONLINE_SHOP; 2 | 3 | INSERT INTO Products ( ProductCategoryID, SupplierID, 4 | ProductName, ProductImage, NetRetailPrice, AvailableQuantity, 5 | WholesalePrice, UnitKGWeight, Notes ) 6 | 7 | VALUES 8 | (4, 1, 'Helios 5', NULL, 24999.99, 22, 17999.99, 15, 9 | 'helium airship'), 10 | (4, 1, 'Arctan Pi', NULL, 84999.99, 3, 77999.99, 2, 11 | 'high-lift freight dirigible'), 12 | (4, 1, 'Fermat Radian', NULL, 199999.95, 18, 185999.99, 13 | 17.4, 'passenger airship'), 14 | (2, 4, 'Hammer', NULL, 39.95, 19, 33.49, 0.5, 15 | 'basic hammer'), 16 | (2, 4, 'Dishwasher Airgap', NULL, 14.95, 34, 10.89, 0.45, 17 | 'countertop airgap'), 18 | (2, 4, 'Flathead Screwdriver', NULL, 7.49, 208, 5.19, 0.15, 19 | 'regular screwdriver'), 20 | (2, 4, 'Phillips Screwdriver', NULL, 7.29, 155, 5.49, 0.15, 21 | 'phillips-head screwdriver'), 22 | (2, 4, 'Pliers', NULL, 19.95, 44, 15.23, 0.45, 'pliers'), 23 | (6, 4, 'Wealth of Nations', NULL, 24.95, 144, 19.49, 0.65, 24 | 'Great economics book'); 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Packt Workshops 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Chapter04/Customers1.sql: -------------------------------------------------------------------------------- 1 | create table Customers1 2 | ( 3 | FirstName varchar(50) , 4 | MiddleName varchar(50) , 5 | LastName varchar(50) , 6 | HomeAddress varchar(250) , 7 | Email varchar(200) , 8 | Phone varchar(50) , 9 | Notes varchar(250) 10 | ); 11 | INSERT INTO Customers1 ( FirstName, MiddleName, LastName, HomeAddress, Email, Phone, Notes ) 12 | VALUES('Joe', 'Greg', 'Smith', '2356 Elm St.', 'joesmith@sfghwert.com', '(310) 555-1212', 'Always gets products home delivered'), 13 | ('Grace', 'Murray', 'Hopper', '123 Compilation Street', 'gmhopper@ftyuw46.com', '(818) 555-3678', 'Compiler pioneer'), 14 | ('Ada', NULL, 'Lovelace', '22 Algorithm Way', 'adalovelace@fgjw54af.gov', '(717) 555-3457', 'First software engineer'), 15 | ('Joseph', 'Force', 'Crater', '1313 Mockingbird Lane', 'judgecrater@ev56gfwrty.com', '(212) 555-5678', 'Works everyday'), 16 | ('Jacqueline', 'Jackie', 'Cochran', '1701 Flightspeed Avenue', 'jackiecochrane@jryuwp8qe4w.gov', '(717) 555-3457', 'Researcher'), 17 | (NULL, 'Paul', 'Jones', '126 Bonhomme Richard Ave.', 'jpjones@bonhommerichard.edu', '(216) 555-6232', 'Admiral'), 18 | ('Grace', 'NULL', 'Park', '5 Hollywood', 'gpark@ftyuw46.gov', '(310) 666-3678', 'Actor'), 19 | ('Stephen', 'William', 'Hawking', '4 Cambridge', 'stephenh@cambridge.gov', '(454) 4444-9900', 'Professor of Mathematics'), 20 | ('Stephen', 'NULL', 'Hillenburg ', '100 LA', 'shillenburg@la.gov', '(454) 4433-9000', 'Director'); 21 | -------------------------------------------------------------------------------- /Chapter05/Needs to be deleted: -------------------------------------------------------------------------------- 1 | create table Customers1 2 | ( 3 | FirstName nvarchar(50) , 4 | MiddleName nvarchar(50) , 5 | LastName nvarchar(50) , 6 | HomeAddress nvarchar(250) , 7 | Email nvarchar(200) , 8 | Phone nvarchar(50) , 9 | Notes nvarchar(250) 10 | ); 11 | INSERT INTO Customers1 ( FirstName, MiddleName, LastName, HomeAddress, Email, Phone, Notes ) 12 | VALUES('Joe', 'Greg', 'Smith', '2356 Elm St.', 'joesmith@sfghwert.com', '(310) 555-1212', 'Always gets products home delivered'), 13 | ('Grace', 'Murray', 'Hopper', '123 Compilation Street', 'gmhopper@ftyuw46.com', '(818) 555-3678', 'Compiler pioneer'), 14 | ('Ada', NULL, 'Lovelace', '22 Algorithm Way', 'adalovelace@fgjw54af.gov', '(717) 555-3457', 'First software engineer'), 15 | ('Joseph', 'Force', 'Crater', '1313 Mockingbird Lane', 'judgecrater@ev56gfwrty.com', '(212) 555-5678', 'Works everyday'), 16 | ('Jacqueline', 'Jackie', 'Cochran', '1701 Flightspeed Avenue', 'jackiecochrane@jryuwp8qe4w.gov', '(717) 555-3457', 'Researcher'), 17 | (NULL, 'Paul', 'Jones', '126 Bonhomme Richard Ave.', 'jpjones@bonhommerichard.edu', '(216) 555-6232', 'Admiral'), 18 | ('Grace', 'NULL', 'Park', '5 Hollywood', 'gpark@ftyuw46.gov', '(310) 666-3678', 'Actor'), 19 | ('Stephen', 'William', 'Hawking', '4 Cambridge', 'stephenh@cambridge.gov', '(454) 4444-9900', 'Professor of Mathematics'), 20 | ('Stephen', 'NULL', 'Hillenburg ', '100 LA', 'shillenburg@la.gov', '(454) 4433-9000', 'Director'); 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /Chapter01/Activity Sol: -------------------------------------------------------------------------------- 1 | /* Activity 1.01: Inserting Values into the Products Table in the PACKT_ONLINE_SHOP Database */ 2 | /* 1. Create the Products table with the same column names that were provided in the Excel spreadsheet: */ 3 | CREATE TABLE Products 4 | ( 5 | ProductID INT NOT NULL AUTO_INCREMENT, 6 | ProductCategoryID INT NOT NULL, 7 | SupplierID INT NOT NULL, 8 | ProductName CHAR(50) NOT NULL, 9 | NetRetailPrice DECIMAL(10, 2) NULL, 10 | AvailableQuantity INT NOT NULL, 11 | WholesalePrice DECIMAL(10, 2) NOT NULL, 12 | UnitKGWeight DECIMAL(10, 5) NULL, 13 | Notes VARCHAR(750) NULL, 14 | PRIMARY KEY (ProductID) 15 | ); 16 | /* 2. Enter the values into the Products table: */ 17 | INSERT INTO Products ( ProductCategoryID, SupplierID, ProductName, NetRetailPrice, AvailableQuantity, WholesalePrice, UnitKGWeight, Notes ) 18 | VALUES 19 | (5, 2, 'Calculatre', 24.99, 100, 17.99, 1, 'calculation application'), 20 | (5, 5, 'Penwrite', 79.99, 27, 49.99, 2, 'word processing product'), 21 | (1, 6, 'Vortex Generator', 2499.99, 1000, 1999.99, 0.01, 'space engine component'), 22 | (1, 6, 'The Gourmet Crockpot', 24.99, 72, 19.99, 1.63, 'cookbook'), 23 | (1, 6, 'Account Books', 14.99, 26, 9.99, 1.22, 'government accounting book'), 24 | (3, 6, 'habanero peppers', 4.49, 189, 2.99, 0.009, 'hot peppers'), 25 | (2, 1, '10-mm socket wrench', 3.49, 39, 1.89, 0.018, 'important tool'), 26 | (3, 4, 'tomato sauce', 1.19, 1509, 0.89, 0.232, 'bottled in glass'), 27 | (1, 6, 'pure vanilla', 10.39, 1509, 7.89, 0.032, 'high-quality vanilla'), 28 | (3, 2, 'keyboard wrench', 399999.95, 6128, 149999.99, 521.38, 'handle with care'), 29 | (2, 1, 'power cell', 47.89, 2346, 29.99, 0.298, 'ten amp-hours per cell'); 30 | -------------------------------------------------------------------------------- /Chapter01/Activity 1.01.csv: -------------------------------------------------------------------------------- 1 | ProductID,ProductCategoryID,SupplierID,ProductName,NetRetailPrice,AvailableQuantity,WholesalePrice,UnitKGWeight,Notes ,,,,,,,,, 2 | 1,5,2,Calculatre,$24.99,100,$17.99,1,calculation application,,,,,,,,, 3 | 2,5,5,Penwrite,$79.99,27,$49.99,2,word processing product,,,,,,,,, 4 | 3,1,6,Vortex Generator,"$2,499.99",1000,"$1,999.99",0.01,space engine component,,,,,,,,, 5 | 4,1,6,The Gourmet Crockpot,$24.99,72,$19.99,1.63,cookbook,,,,,,,,, 6 | 5,1,6,Government Accounting,$14.99,26,$9.99,1.22,government accounting book,,,,,,,,, 7 | 6,3,6,habanero peppers,$4.49,189,$2.99,0.009,hot peppers,,,,,,,,, 8 | 7,2,1,10-mm socket wrench,$3.49,39,$1.89,0.018,important tool,,,,,,,,, 9 | 8,3,4,tomato sauce,$1.19,1509,$0.89,0.232,bottled in glass,,,,,,,,, 10 | 9,1,6,pure vanilla,$10.39,1509,$7.89,0.032,high-quality vanilla,,,,,,,,, 11 | 10,3,2,keyboard wrench,"$399,999.95",6128,"$149,999.99",521.38,handle with care,,,,,,,,, 12 | 11,2,1,power cell,$47.89,2346,$29.99,0.298,ten amp-hours per cell,,,,,,,,, 13 | ,,,,,,,,,,,,,,,,, 14 | ,,,,,,,,,,,,,,,,, 15 | ,,,,,,,,,,,,,,,,, 16 | ,,,,,,,,,,,,,,,,, 17 | ,,,,,,,,,,,,,,,,, 18 | ,,,,,,,,,,,,,,,,, 19 | ,,,,,,,,,,,,,,,,, 20 | ,,,,,,,,,,,,,,,,, 21 | ,,,,,,,,,,,,,,,,, 22 | ,,,,,,,,,,1,6,The Gourmet Crockpot,$24.99,72,$19.99,1.63,cookbook 23 | ,,,,,,,,,,1,6,Government Accounting,$14.99,26,$9.99,1.22,government accounting book 24 | ,,,,,,,,,,3,6,habanero peppers,$4.49,189,$2.99,0.009,hot peppers 25 | ,,,,,,,,,,2,1,10-mm socket wrench,$3.49,39,$1.89,0.018,important tool 26 | ,,,,,,,,,,3,4,tomato sauce,$1.19,1509,$0.89,0.232,bottled in glass 27 | ,,,,,,,,,,1,6,pure vanilla,$10.39,1509,$7.89,0.032,high-quality vanilla 28 | ,,,,,,,,,,3,2,keyboard wrench,"$399,999.95",6128,"$149,999.99",521.38,handle with care 29 | ,,,,,,,,,,2,1,power cell,$47.89,2346,$29.99,0.298,ten amp-hours per cell -------------------------------------------------------------------------------- /Chapter08/tr_Products_OnInsert: -------------------------------------------------------------------------------- 1 | USE packt_online_shop; 2 | 3 | # drop trigger tr_Products_OnInsert 4 | 5 | DELIMITER $$ 6 | 7 | # Basic syntax to create the tr_Products_OnInsert trigger 8 | # to fire after every OrderItems table row insertion. 9 | 10 | CREATE TRIGGER tr_Products_OnInsert AFTER INSERT ON Products 11 | FOR EACH ROW 12 | BEGIN 13 | 14 | /* 15 | To test: INSERT INTO Products(ProductCategoryID, SupplierID, 16 | ProductName, ProductImage, NetRetailPrice, 17 | AvailableQuantity, WholesalePrice, 18 | UnitKGWeight, Notes) 19 | 20 | VALUES(3, 3, 'peanut butter', NULL, 3.79, 1000, 2.69, 21 | 0.75, 'caution: high calorie'); 22 | 23 | SELECT P.* 24 | FROM Products P 25 | WHERE P.SupplierID = 3; 26 | */ 27 | 28 | DECLARE supplierID INT; 29 | DECLARE supplierProductCount INT; 30 | DECLARE supplierCountText VARCHAR(1000); 31 | 32 | # The "NEW" table has the SupplierID 33 | # value we'll need 34 | 35 | SET supplierID = ( 36 | SELECT NEW.supplierID 37 | ); 38 | 39 | # Calculate the supplier product count, 40 | # and convert the value to TEXT 41 | 42 | SET supplierProductCount = ( 43 | SELECT COUNT(P.ProductID) 44 | FROM Products P INNER JOIN 45 | Suppliers S ON 46 | P.SupplierID = S.SupplierID 47 | WHERE S.SupplierID = supplierID 48 | ); 49 | 50 | SET supplierCountText = ( 51 | SELECT CONCAT("This supplier (Supplier ", CAST(supplierID AS CHAR), ")") 52 | ); 53 | 54 | SET supplierCountText = ( 55 | SELECT CONCAT(supplierCountText, " has ", CAST(supplierProductCount AS CHAR)) 56 | ); 57 | 58 | SET supplierCountText = ( 59 | SELECT CONCAT(supplierCountText, " products available here at Packt as of ") 60 | ); 61 | 62 | SET supplierCountText = ( 63 | SELECT CONCAT(supplierCountText, DATE_FORMAT(NOW(), "%b %d, %Y")) 64 | ); 65 | 66 | # Update the Customers.BalanceNotes column 67 | # for that specific customerID 68 | 69 | UPDATE Suppliers 70 | SET Suppliers.Notes = supplierCountText 71 | WHERE Suppliers.SupplierID = supplierID; 72 | 73 | END$$ 74 | 75 | DELIMITER ; 76 | -------------------------------------------------------------------------------- /Chapter05/Chapter 5 Scripts.sql: -------------------------------------------------------------------------------- 1 | /*The WHERE Clause Syntax*/ 2 | USE studentdemo; 3 | SELECT * 4 | FROM Student; 5 | 6 | SELECT * 7 | FROM Student 8 | WHERE course = 'Electronics'; 9 | 10 | /* Exercise 5.01: Implementing Logical Operators in the WHERE Clause */ 11 | 12 | USE PACKT_ONLINE_SHOP; 13 | SELECT ProductName AS 'High-value Products', NetRetailPrice 14 | FROM Products 15 | WHERE NetRetailPrice > 14.99 16 | 17 | USE PACKT_ONLINE_SHOP; 18 | SELECT ProductName AS [High-value Products], NetRetailPrice 19 | FROM Products 20 | WHERE NetRetailPrice >= 14.99 21 | 22 | /*Exercise 5.02: Using the BETWEEN Operator*/ 23 | SELECT ProductName,NetRetailPrice 24 | FROM Products 25 | WHERE NetRetailPrice BETWEEN 14.99 AND 50 26 | ORDER BY NetRetailPrice; 27 | 28 | /* Exercise 5.03: Using the != and <> Operators */ 29 | 30 | SELECT ProductName,NetRetailPrice 31 | FROM Products 32 | WHERE ProductName != 'tomato sauce' 33 | ORDER BY NetRetailPrice; 34 | 35 | SELECT ProductName,NetRetailPrice 36 | FROM Products 37 | WHERE ProductName <> 'tomato sauce' 38 | ORDER BY NetRetailPrice; 39 | 40 | /*The LIKE Operator*/ 41 | 42 | SELECT FirstName, LastName, Phone 43 | FROM Customers 44 | WHERE FirstName LIKE '_o%'; 45 | 46 | /*Exercise 5.04: Using the LIKE Operator to Check a Pattern at the Beginning of a String8/ 47 | 48 | SELECT FirstName AS 'Customers from LA', Phone 49 | FROM Customers 50 | WHERE Phone LIKE '(310)%'; 51 | 52 | /*Exercise 5.05: Using the LIKE Operator to Check for a Specified Length*/ 53 | 54 | SELECT FirstName, LastName, Phone 55 | FROM Customers 56 | WHERE FirstName LIKE '___'; 57 | 58 | /*Exercise 5.06: Searching for NULL Values*/ 59 | 60 | SELECT MiddleName, LastName, Phone 61 | FROM Customers 62 | WHERE FirstName IS NULL; 63 | 64 | /*Exercise 5.07: Querying Multiple Conditions*/ 65 | 66 | SELECT * 67 | FROM Customers 68 | WHERE FirstName = 'Joe' AND Phone LIKE '(310)%'; 69 | 70 | SELECT FirstName, LastName, Phone 71 | FROM Customers 72 | WHERE FirstName = 'Joe' OR Phone LIKE '(310)%'; 73 | 74 | SELECT FirstName, LastName, Phone,Notes 75 | FROM Customers 76 | WHERE FirstName LIKE 'Jo%' AND (Phone LIKE '(310)%' OR Phone LIKE '(210)%') AND NOT LastName = 'Carter'; 77 | 78 | -------------------------------------------------------------------------------- /Chapter04/Chapter 4: -------------------------------------------------------------------------------- 1 | /* Retrieving All Columns of a Table */ 2 | use PACKT_ONLINE_SHOP; 3 | SELECT * FROM ProductCategories; 4 | 5 | /* Exercise 4.01: Selecting Columns from a Table */ 6 | 7 | use PACKT_ONLINE_SHOP; 8 | SELECT ProductCategoryID, ProductCategoryName 9 | FROM ProductCategories; 10 | 11 | SELECT ProductCategoryName, ProductCategoryID 12 | FROM ProductCategories; 13 | 14 | /* Exercise 4.02: Aliasing the Column Headers */ 15 | SELECT ProductCategoryName AS CATEGORY, ProductCategoryID AS ID 16 | FROM ProductCategories; 17 | 18 | SELECT ProductCategoryName AS 'PRODUCT CATEGORY', ProductCategoryID AS ID 19 | FROM ProductCategories; 20 | 21 | /* Ordering Rows According to a Particular Column */ 22 | 23 | SELECT ProductCategoryName AS 'CATEGORY NAME', ProductCategoryID AS ID 24 | FROM ProductCategories 25 | ORDER BY ProductCategoryName ASC; 26 | 27 | SELECT ProductCategoryName AS 'CATEGORY NAME', ProductCategoryID AS ID 28 | FROM ProductCategories 29 | ORDER BY 'CATEGORY NAME' DESC; 30 | 31 | /* Ordering Rows According to Multiple Columns */ 32 | SELECT FirstName, CustomerID 33 | FROM Customers; 34 | 35 | SELECT FirstName, CustomerID 36 | FROM Customers 37 | ORDER BY FirstName, CustomerID DESC; 38 | 39 | SELECT FirstName, CustomerID 40 | FROM Customers 41 | ORDER BY 1, 2; 42 | 43 | SELECT FirstName, CustomerID 44 | FROM Customers 45 | ORDER BY 1 DESC, 2 DESC; 46 | 47 | /* Exercise 4.03: Using the LIMIT Keyword */ 48 | SELECT ProductName, NetRetailPrice 49 | FROM Products 50 | ORDER BY NetRetailPrice DESC 51 | LIMIT 5; 52 | 53 | SELECT ProductName, NetRetailPrice 54 | FROM Products 55 | ORDER BY NetRetailPrice 56 | LIMIT 4; 57 | 58 | /* Using DISTINCT */ 59 | 60 | SELECT DISTINCT FirstName, LastName 61 | FROM Customers1; 62 | 63 | SELECT DISTINCT FirstName 64 | FROM Customers1; 65 | 66 | /*Exercise 4.05: Calculating the Line Item Total */ 67 | 68 | SELECT ProductID, Quantity, UnitPrice, (Quantity*UnitPrice) AS 'Line Item Total' 69 | FROM OrderItems; 70 | 71 | /* Exercise 4.06: Calculating Discount */ 72 | 73 | SELECT ProductID, Quantity, UnitPrice, (Quantity*UnitPrice) AS 'Line Item Total', Discount, ((Quantity*UnitPrice)-(Quantity*Discount)) AS 'Price After Discount' 74 | FROM OrderItems; 75 | 76 | -------------------------------------------------------------------------------- /Chapter06/Chapter 6 Scripts.sql: -------------------------------------------------------------------------------- 1 | /*Exercise 6.01 Implementing Inner Join*/ 2 | SELECT Orders.OrderNumber, Orders.OrderStatus, Orders.OrderDate, Customers.FirstName, Customers.LastName, Customers.Email 3 | FROM Orders JOIN Customers ON Orders.CustomerID = Customers.CustomerID; 4 | 5 | /* Exercise 6.02: Implementing RIGHT JOIN*/ 6 | 7 | SELECT Customers.FirstName, 8 | Customers.LastName, 9 | Customers.Email , 10 | Orders.OrderNumber, 11 | Orders.OrderStatus 12 | 13 | FROM Orders RIGHT JOIN Customers ON Orders.CustomerID = Customers.CustomerID 14 | 15 | /*Exercise 6.03: Implementing LEFT JOIN*/ 16 | SELECT Orders.OrderNumber, 17 | Orders.OrderStatus, 18 | Payments.PaymentRef, 19 | Payments.PaymentType 20 | 21 | FROM Payments LEFT JOIN Orders ON Payments.OrderID = Orders.OrderID 22 | 23 | SELECT Orders.OrderNumber, 24 | Orders.OrderStatus, 25 | Payments.PaymentRef, 26 | Payments.PaymentType 27 | 28 | FROM Orders LEFT JOIN Payments ON Payments.OrderID = Orders.OrderID 29 | 30 | /*Exercise 6.04: Implementing FULL JOIN*/ 31 | SELECT Orders.OrderNumber, 32 | Orders.OrderStatus, 33 | Customers.FirstName, 34 | Customers.LastName 35 | 36 | FROM Orders FULL JOIN Customers ON Orders.CustomerID = Customers.CustomerID 37 | 38 | /* Exercise 6.05: Implementing CROSS JOINS */ 39 | Create table Facecards (cardvalue varchar (50)); 40 | insert into Facecards (cardvalue) values ('King'); 41 | insert into Facecards (cardvalue) values ('Queen'); 42 | insert into Facecards (cardvalue) values ('Jack'); 43 | insert into Facecards (cardvalue) values ('Ace'); 44 | 45 | Create table CardSuit (suit varchar(50)); 46 | insert into CardSuit (suit) values ('Heart'); 47 | insert into CardSuit (suit) values ('Spade'); 48 | insert into CardSuit (suit) values ('Clubs'); 49 | insert into CardSuit (suit) values ('Diamond'); 50 | 51 | SELECT Facecards.cardvalue, 52 | CardSuit.suit 53 | 54 | FROM Facecards CROSS JOIN CardSuit; 55 | 56 | /*Exercise 6.06: Implementing a UNION JOIN*/ 57 | SELECT CONCAT(Customers.FirstName,' ',Customers.LastName) as 'FULL NAME', 58 | Customers.Phone AS 'Phone Number' 59 | FROM Customers 60 | UNION 61 | SELECT Suppliers.ContactPerson AS'Full Name', 62 | Suppliers.PhoneNumber AS 'Phone Number' 63 | FROM Suppliers 64 | 65 | 66 | -------------------------------------------------------------------------------- /Chapter02/Activity: -------------------------------------------------------------------------------- 1 | Example 1: 2 | 3 | --To create a database, all you do is send the CREATE DATABASE command along with the name you wish your database 4 | 5 | CREATE DATABASE PACKT_ONLINE_SHOP; 6 | 7 | Example 2: 8 | 9 | --To create the database conditionally. If the database already exists, we will drop the existing database and create a new one. Else, we will simply create a new database. 10 | 11 | CREATE DATABASE IF NOT EXISTS PACKT_ONLINE_SHOP; 12 | 13 | Exmaple 3: 14 | 15 | --To check configuration information of the newly created database can be found by running 16 | 17 | mysql –help 18 | 19 | Example 4: 20 | 21 | --To review the created database command by running the SHOW CREATE DATABASE command: 22 | 23 | mysql> SHOW CREATE DATABASE PACKT_ONLINE_SHOP; 24 | 25 | Example 5: 26 | 27 | -- To create table within PACKT_ONLINE_SHOP. 28 | 29 | --To create a Customers table under the PACKT_ONLINE_SHOP database 30 | 31 | USE PACKT_ONLINE_SHOP; 32 | CREATE TABLE Customers 33 | ( 34 | CustomerID INT NOT NULL AUTO_INCREMENT, 35 | FirstName CHAR(50) NOT NULL, 36 | LastName CHAR(50) NOT NULL, 37 | Address CHAR(250) NULL, 38 | Email CHAR(200) NULL, 39 | Phone CHAR(50) NULL, 40 | Notes TEXT(1024) NULL, 41 | PRIMARY KEY (CustomerID) 42 | ); 43 | 44 | Example 6: 45 | 46 | --To Insert sample rows run the following command 47 | 48 | INSERT INTO Customers (FirstName, LastName, Address, Email, Phone, Notes) 49 | VALUES 50 | ('Joe', 'Doaks', '2356 Elm St.', 'joedoaks@sfghwert.com', '(310) 555-1212', 'A note'), 51 | ('Paul', 'Atreides', '123 Caladan Drive', 'patreides@sietchtabr.com', '(818) 555-3678', 'Outworlder, now a Fremen'), 52 | ('Mr.', 'Spock', '1701 Enterprise Drive', 'mrspock@NCC1701Enterprise.gov', '(717) 555-3457', 'Perceptive naval and science officer'), 53 | ('Joseph', 'Crater', '1313 Mockingbird Lane', 'judgecrater@e56gfwrty.com', '(212) 555-5678', 'Might undisappear any minute . . .'), 54 | ('James', 'Kirk', '1701 Enterprise Drive', 'jtkirk@NCC1701Enterprise.gov', '(717) 555-3457', 'Naval combat veteran'), 55 | ('Luke', 'Skywalker', '456 Tosche Station', 'lskywalker@moseisley.gov', '(213) 555-3421', 'Pilot and mystic'), 56 | ('Chew', 'Bacca', 'Docking Bay 94, Kashyyyk', 'chewbacca@rebelalliance.edu', '(213) 555-8523', 'Executive Officer, Millennium Falcon'), 57 | ('Leto', 'Atreides', '1870 Arrakeen Ct.', 'latreides@arrakeen.org', '(310) 555-5462', 'Spice dealer'); 58 | 59 | Example 7: 60 | 61 | --Add a new column to the existing Customer table, called ZipCode, which will contain the ZIP code. 62 | 63 | ALTER TABLE Customers 64 | ADD COLUMN ZipCode INT CONSTRAINT CHK_ZipCode 65 | CHECK ([ZipCode] LIKE '[0-9][0-9][0-9][0-9][0-9]'); 66 | 67 | Example 8: 68 | /* 69 | How to modify an existing column in a table. This is done using the MODIFY clause with the ALTER TABLE command. 70 | To expand the character limit for the firstName and the lastName columns of the Customer table, run the following command 71 | */ 72 | ALTER TABLE Customers 73 | MODIFY COLUMN firstName char(100), 74 | MODIFY COLUMN lastName char(100) 75 | 76 | -------------------------------------------------------------------------------- /Chapter08/tr_OrderItems_OnInsert.sql: -------------------------------------------------------------------------------- 1 | USE packt_online_shop; 2 | 3 | # drop trigger tr_OrderItems_OnInsert 4 | 5 | DELIMITER $$ 6 | 7 | # Basic syntax to create the tr_OrderItems_OnInsert trigger 8 | # to fire after every OrderItems table row insertion. 9 | 10 | CREATE TRIGGER tr_OrderItems_OnInsert AFTER INSERT ON OrderItems 11 | FOR EACH ROW 12 | BEGIN 13 | 14 | /* 15 | To test: INSERT INTO OrderItems(OrderID, ProductID, Quantity, 16 | UnitPrice, Discount, Notes) 17 | VALUES(1, 6, 12, 4.49, 0.00, NULL); 18 | 19 | SELECT C.BalanceNotes 20 | FROM Customers C 21 | WHERE C.CustomerID = 2; 22 | */ 23 | 24 | # Assign the needed variable values, in order. 25 | # SELECT the values and assign then to the 26 | # variables with the SET command. For this, 27 | # place all SELECT statements in parentheses. 28 | 29 | DECLARE balanceNotesText VARCHAR(1000); 30 | DECLARE customerID INT; 31 | DECLARE orderBalance DECIMAL(10, 2); 32 | DECLARE orderIDVal INT; 33 | DECLARE paymentBalance DECIMAL(10, 2); 34 | DECLARE runningTotal VARCHAR(50); 35 | 36 | # The "NEW" table has the CustomerID and OrderID values 37 | # from the new inserted row that we'll need. 38 | 39 | SET orderIDVal = ( 40 | SELECT NEW.orderID 41 | ); 42 | 43 | SET customerID = ( 44 | SELECT O.CustomerID 45 | FROM Orders O 46 | WHERE OrderID = orderIDVal 47 | ); 48 | 49 | # Calculate the order balance for the customer 50 | 51 | SET orderBalance = ( 52 | SELECT SUM(OI.Quantity * (OI.UnitPrice - OI.Discount)) 53 | FROM OrderItems OI INNER JOIN Orders O ON 54 | OI.OrderID = O.OrderID 55 | WHERE O.CustomerID = CustomerID 56 | ); 57 | 58 | # Calculate the payment balance for the customer 59 | 60 | SET paymentBalance = ( 61 | SELECT SUM(P.Amount) 62 | FROM Payments P INNER JOIN Orders O ON 63 | P.OrderID = O.OrderID 64 | WHERE O.CustomerID = CustomerID 65 | ); 66 | 67 | # Calculate the running total, and convert the value to CHAR 68 | 69 | SET runningTotal = ( 70 | SELECT CAST((orderBalance - paymentBalance) AS CHAR) 71 | ); 72 | 73 | # Build the balanceNotesText string 74 | 75 | SET balanceNotesText = ( 76 | SELECT CONCAT("Customer ", CAST(customerID AS CHAR)) 77 | ); 78 | 79 | SET balanceNotesText = ( 80 | SELECT CONCAT(balanceNotesText, " has a new running balance of $") 81 | ); 82 | 83 | # 84 | # The NOW() function has the datestamp value we need; 85 | # use the CONVERT function to format the datestamp value 86 | # 87 | 88 | SET balanceNotesText = ( 89 | SELECT CONCAT(balanceNotesText, runningTotal, ' as of ') 90 | ); 91 | 92 | SET balanceNotesText = ( 93 | SELECT CONCAT(balanceNotesText, DATE_FORMAT(NOW(), "%b %d, %Y")) 94 | ); 95 | 96 | # Update the Customers.BalanceNotes column for that specific customerID 97 | 98 | UPDATE Customers 99 | SET Customers.BalanceNotes = balanceNotesText 100 | WHERE Customers.CustomerID = customerID; 101 | 102 | END$$ 103 | 104 | DELIMITER ; 105 | -------------------------------------------------------------------------------- /SCRIPTS/MYSQL SCRIPTS/MYSQL_create_database_script.sql: -------------------------------------------------------------------------------- 1 | DROP DATABASE IF EXISTS PACKT_ONLINE_SHOP; 2 | CREATE DATABASE IF NOT EXISTS PACKT_ONLINE_SHOP; 3 | USE PACKT_ONLINE_SHOP; 4 | 5 | CREATE TABLE Customers 6 | ( 7 | CustomerID INT NOT NULL AUTO_INCREMENT, 8 | FirstName CHAR(50) NULL, 9 | MiddleName CHAR(50) NULL, 10 | LastName CHAR(50) NULL, 11 | Address CHAR(250) NULL, 12 | Email CHAR(200) NULL, 13 | Phone CHAR(50) NULL, 14 | Notes VARCHAR(750) NULL, 15 | BalanceNotes VARCHAR(750) NULL, 16 | PRIMARY KEY (CustomerID) 17 | ); 18 | 19 | CREATE TABLE OrderItems 20 | ( 21 | OrderItemID INT NOT NULL AUTO_INCREMENT, 22 | OrderID INT NOT NULL, 23 | ProductID INT NOT NULL, 24 | Quantity INT NOT NULL, 25 | UnitPrice DECIMAL(10, 2) NOT NULL, 26 | Discount DECIMAL(10, 2) NULL, 27 | Notes VARCHAR(750) NULL, 28 | PRIMARY KEY (OrderItemID) 29 | ); 30 | 31 | CREATE TABLE Orders 32 | ( 33 | OrderID INT NOT NULL AUTO_INCREMENT, 34 | CustomerID INT NOT NULL, 35 | OrderNumber CHAR(50) NOT NULL, 36 | OrderDate DATETIME NOT NULL, 37 | ShipmentDate DATETIME NULL, 38 | OrderStatus CHAR(10) NULL, 39 | Notes VARCHAR(750) NULL, 40 | PRIMARY KEY (OrderID) 41 | ); 42 | 43 | CREATE TABLE Payments 44 | ( 45 | PaymentID INT NOT NULL AUTO_INCREMENT, 46 | OrderID INT NOT NULL, 47 | PaymentDate DATETIME NOT NULL, 48 | PaymentType CHAR(50) NULL, 49 | PaymentRef CHAR(50) NULL, 50 | Amount DECIMAL(10, 2) NOT NULL, 51 | Notes VARCHAR(750) NULL, 52 | BalanceNotes VARCHAR(750) NULL, 53 | PRIMARY KEY (PaymentID, OrderID) 54 | ); 55 | 56 | CREATE TABLE ProductCategories 57 | ( 58 | ProductCategoryID INT NOT NULL AUTO_INCREMENT, 59 | ProductCategoryName CHAR(50) NOT NULL, 60 | Notes VARCHAR(750) NULL, 61 | PRIMARY KEY (ProductCategoryID) 62 | ); 63 | 64 | CREATE TABLE Products 65 | ( 66 | ProductID INT NOT NULL AUTO_INCREMENT, 67 | ProductCategoryID INT NOT NULL, 68 | SupplierID INT NOT NULL, 69 | ProductName CHAR(50) NOT NULL, 70 | ProductImage MEDIUMBLOB NULL, 71 | NetRetailPrice DECIMAL(10, 2) NULL, 72 | AvailableQuantity INT NOT NULL, 73 | WholesalePrice DECIMAL(10, 2) NOT NULL, 74 | UnitKGWeight DECIMAL(10, 5) NULL, 75 | Notes VARCHAR(750) NULL, 76 | PRIMARY KEY (ProductID) 77 | ); 78 | 79 | CREATE TABLE Suppliers 80 | ( 81 | SupplierID INT NOT NULL AUTO_INCREMENT, 82 | SupplierName CHAR(50) NOT NULL, 83 | Country CHAR(50) NOT NULL, 84 | Address CHAR(50) NULL, 85 | PhoneNumber CHAR(50) NULL, 86 | ContactPerson CHAR(50) NULL, 87 | Notes VARCHAR(750) NULL, 88 | PRIMARY KEY (SupplierID) 89 | ); 90 | 91 | ALTER TABLE Orders 92 | ADD FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID); 93 | 94 | ALTER TABLE OrderItems 95 | ADD FOREIGN KEY (OrderID) REFERENCES Orders(OrderID); 96 | 97 | ALTER TABLE OrderItems 98 | ADD FOREIGN KEY (ProductID) REFERENCES Products(ProductID); 99 | 100 | ALTER TABLE Payments 101 | ADD FOREIGN KEY (OrderID) REFERENCES Orders(OrderID); 102 | 103 | ALTER TABLE Products 104 | ADD FOREIGN KEY (SupplierID) REFERENCES Suppliers(SupplierID); 105 | 106 | ALTER TABLE Products 107 | ADD FOREIGN KEY (ProductCategoryID) REFERENCES ProductCategories(ProductCategoryID); 108 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The SQL Workshop 2 | [![GitHub issues](https://img.shields.io/github/issues/PacktWorkshops/The-SQL-Workshop.svg)](https://github.com/PacktWorkshops/The-SQL-Workshop/issues) 3 | [![GitHub forks](https://img.shields.io/github/forks/PacktWorkshops/The-SQL-Workshop.svg)](https://github.com/PacktWorkshops/The-SQL-Workshop/network) 4 | [![GitHub stars](https://img.shields.io/github/stars/PacktWorkshops/The-SQL-Workshop.svg)](https://github.com/PacktWorkshops/The-SQL-Workshop/stargazers) 5 | [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/PacktWorkshops/The-SQL-Workshop/pulls) 6 | 7 | This is the repository for [The SQL Workshop](https://www.amazon.com/SQL-Workshop-Interactive-Approach-Learning/dp/1838642358/ref=sr_1_1?dchild=1&keywords=The%20SQL%20Workshop&qid=1610708551&sr=8-1&utm_source=github&utm_medium=repository&utm_campaign=9781838642358&utm_term=SQL&utm_content=The%20SQL%20Workshop), published by [Packt](https://www.packtpub.com/?utm_source=github). It contains all the supporting project files necessary to work through the course from start to finish. 8 | 9 | ## Requirements and Setup 10 | The SQL Workshop 11 | 12 | To get started with the project files, you'll need to install [MySQL](https://dev.mysql.com/doc/mysql-installation-excerpt/8.0/en/) 13 | 14 | Please note that the SCRIPTS directory has two subdirectories 15 | 16 | * /MYSQL SCRIPTS 17 | * /SQL SERVER SCRIPTS 18 | 19 | Each of these subdirectories has two files. One file builds the appropriate PACKT ONLINE SHOP database structure - tables, columns, relations - for MySQL or SQL Server, and one file inserts MySQL or SQL Server data rows into the appropriate database structure. 20 | 21 | ## About The SQL Workshop 22 | Filled with practical examples and realistic exercises, [The SQL Workshop](https://www.amazon.com/SQL-Workshop-Interactive-Approach-Learning/dp/1838642358/ref=sr_1_1?dchild=1&keywords=The%20SQL%20Workshop&qid=1610708551&sr=8-1&utm_source=github&utm_medium=repository&utm_campaign=9781838642358&utm_term=SQL&utm_content=The%20SQL%20Workshop) will get you up to speed with the fundamentals of SQL. You'll learn how to use SQL queries and functions to create and manage relational databases, and apply your new skills to creatively solve real-world problems. 23 | 24 | ## What you will learn 25 | * Create databases and insert data into them 26 | * Use SQL queries to create, read, update, and delete data 27 | * Maintain data integrity and consistency through normalization 28 | * Customize your basic SQL queries to get the desired output 29 | * Refine your database search using the WHERE and HAVING clauses 30 | * Use joins to fetch data from multiple tables and create custom reports 31 | * Improve web application performance by automating processes 32 | * Secure a database with GRANT and REVOKE privileges 33 | 34 | ## Related Books and Workshops 35 | If you've found this repository useful, you might want to check out some of our other workshop titles: 36 | * [MongoDB Fundamentals](https://www.amazon.com/MongoDB-Workshop-Interactive-Approach-Learning/dp/1839210648/ref=sr_1_1?dchild=1&keywords=MongoDB%20Fundamentals&qid=1611064650&s=books&sr=1-1&utm_source=github&utm_medium=repository&utm_campaign=9781839210648&utm_term=MongoDB&utm_content=MongoDB%20Fundamentals) 37 | * [The Applied SQL Data Analytics Workshop](https://www.amazon.com/Applied-SQL-Data-Analytics-Workshop-ebook/dp/B085D91RNK/ref=sr_1_2?crid=1FDBQD0TEVVF9&dchild=1&keywords=applied%20sql%20data%20analytics%20workshop&qid=1610707878&sprefix=applied%20sql%20dat%2Caps%2C330&sr=8-2&utm_source=github&utm_medium=repository&utm_campaign=9781800203679&utm_term=Applied%20SQL%20Data%20Analytics&utm_content=The%20Applied%20SQL%20Data%20Analytics%20Workshop) 38 | * [The Data Analysis Workshop](https://www.amazon.com/Data-Analysis-Workshop-state-art-ebook/dp/B08Q8HXRQ4/ref=sr_1_1?dchild=1&keywords=The%20Data%20Analysis%20Workshop&qid=1610708839&sr=8-1&utm_source=github&utm_medium=repository&utm_campaign=9781839211386&utm_term=Data%20Analysis&utm_content=The%20Data%20Analysis%20Workshop) 39 | -------------------------------------------------------------------------------- /SCRIPTS/MYSQL SCRIPTS/MySQL_create_data.sql: -------------------------------------------------------------------------------- 1 | USE PACKT_ONLINE_SHOP; 2 | 3 | INSERT INTO Customers ( FirstName, MiddleName, LastName, Address, Email, Phone, Notes ) 4 | VALUES 5 | ('Joe', 'Greg', 'Smith', '2356 Elm St.', 'joesmith@sfghwert.com', '(310) 555-1212', 'A note'), 6 | ('Grace', 'Murray', 'Hopper', '123 Compilation Street', 'gmhopper@ftyuw46.com', '(818) 555-3678', 'Compiler pioneer'), 7 | ('Ada', NULL, 'Lovelace', '22 Algorithm Way', 'adalovelace@fgjw54af.gov', '(717) 555-3457', 'First software engineer'), 8 | ('Joseph', 'Force', 'Crater', '1313 Mockingbird Lane', 'judgecrater@ev56gfwrty.com', '(212) 555-5678', 'Might undisappear any minute . . .'), 9 | ('Jacqueline', 'Jackie', 'Cochran', '1701 Flightspeed Avenue', 'jackiecochrane@jryuwp8qe4w.gov', '(717) 555-3457', 'Research aviator'), 10 | ('William', NULL, 'Shakespeare', '456 Old Globe', 'wshakespeare@dyuioety4.gov', '(213) 555-3421', 'Playwright'), 11 | ('Nellie', NULL, 'Bly', '614 Printing Press Way', 'nellie@fthw45asdgf.com', '(213) 555-8523', 'Investigative Journalist'), 12 | ('Yuri', 'Alekseyevich', 'Gagarin', '1 Ad Astra', 'yuri@rheysdagf.edu', '(310) 555-5462', 'First human to space'), 13 | (NULL, 'Paul', 'Jones', '126 Bonhomme Richard Ave.', 'jpjones@bonhommerichard.edu', '(216) 555-6232', 'Admiral'), 14 | (NULL, 'Al', 'Smith', '1818 Eratosthenes Blvd.', 'alsmith@dytsdrg.edu', '(345) 555-5434', 'Writer'), 15 | (NULL, NULL, 'Pythagoras', '32 Hypotenuse Way', 'pythagoras@sdrg.edu', '(260) 555-3461', 'Mathematician'), 16 | (NULL, NULL, 'Bleriot', '55 Rue Montgolfier', 'bleriot@wtrasf.gov', '(818) 555-3562', 'Pilot'), 17 | ('Aristotle', NULL, NULL, '32 Parthenon Way', 'aristotle@ertyasdf.edu', '(310) 555-9182', 'Scholar'), 18 | ('Cicero', NULL, NULL, '25 Appian Way', 'Cicero@ghyu45y.edu', '(310) 555-0822', 'Orator'), 19 | ('Srinivasa', NULL, 'Ramanujan', '123 Bernoulli Number Drive', 'srinivasa@imaginarynumber.edu', '(211) 555-1111', 'Sharp Mathematician'), 20 | ('Orville', NULL, 'Wright', '80 Bicycle Lane', 'owright@sdg98.edu', '(211) 555-4444', 'First pilot'); 21 | 22 | INSERT INTO Suppliers ( SupplierName, Country, Address, PhoneNumber, ContactPerson, Notes ) 23 | VALUES 24 | ('Acme Systems', 'Switzerland', '123 Capital Drive', '(818) 555-3456', 'Smith Johns', 'spaceship company'), 25 | ('Amalgamated Software', 'Antarctica', '771 South Pole Ave.', '(415) 555-2347', 'Smith Johns', 'software company'), 26 | ('AWT', 'USA', '123 Rockefeller Drive', '(212) 555-3783', 'Trippe Juan', 'airline'), 27 | ('Consolidated Products', 'Canada', '771 Winnipeg Way', '(109) 555-4721', 'Allen Wight', 'food and aluminum company'), 28 | ('CHOAM', 'Atlantis', '123 Atlantean Way', '(213) 555-7567', 'Horace Greeley', 'transport services company'), 29 | ('Sliderule Computers', 'USA', '22 Prediction Ave.', '(310) 555-3456', 'Adam Osborne', 'Computer company'); 30 | 31 | INSERT INTO ProductCategories ( ProductCategoryName, Notes ) 32 | VALUES 33 | ('condiments', 'melange, spices of all types and flavorings' ), 34 | ('tools', 'automotive, aviation, medical, and software repair / maintenance devices ' ), 35 | ('food', 'food products for humans and non-humans' ), 36 | ('airships', 'lighter-than-air aircraft' ), 37 | ('software', 'program products for execution on / by computers' ), 38 | ('books', 'bound, multi-page printed material' ), 39 | ('horse-drawn carriages', 'wheeled vehicles pulled by plant-eating non-human animals'); 40 | 41 | INSERT INTO Products ( ProductCategoryID, SupplierID, ProductName, ProductImage, NetRetailPrice, AvailableQuantity, WholesalePrice, UnitKGWeight, Notes ) 42 | VALUES 43 | (5, 2, 'Calculatre', NULL, 24.99, 100, 17.99, 1, 'calculation application'), 44 | (5, 5, 'Penwrite', NULL, 79.99, 27, 49.99, 2, 'word processing product'), 45 | (1, 6, 'Vortex Generator', NULL, 2499.99, 1000, 1999.99, 0.01, 'space engine component'), 46 | (1, 6, 'The Gourmet Crockpot', NULL, 24.99, 72, 19.99, 1.63, 'cookbook'), 47 | (1, 6, 'Government Accounting', NULL, 14.99, 26, 9.99, 1.22, 'government accounting book'), 48 | (3, 6, 'habanero peppers', NULL, 4.49, 189, 2.99, 0.009, 'hot peppers'), 49 | (2, 1, '10-mm socket wrench', NULL, 3.49, 39, 1.89, 0.018, 'important tool'), 50 | (3, 4, 'tomato sauce', NULL, 1.19, 1509, 0.89, 0.232, 'bottled in glass'), 51 | (1, 6, 'pure vanilla', NULL, 10.39, 1509, 7.89, 0.032, 'high-quality vanilla'), 52 | (3, 2, 'keyboard wrench', NULL, 399999.95, 6128, 149999.99, 521.38, 'handle with care'), 53 | (2, 1, 'power cell', NULL, 47.89, 2346, 29.99, 0.298, 'ten amp-hours per cell'); 54 | 55 | INSERT INTO Orders ( CustomerID, OrderNumber, OrderDate, ShipmentDate, OrderStatus, Notes ) 56 | VALUES 57 | (2, 'ABC123', '20170302', '20170212', 'shipped', 'shipped on time'), 58 | (3, 'BCQ857', '23170307', '23170308', 'pending', 'for appropriate products, fully charge all power cells before packing'), 59 | (4, 'RST321', '19300419', '19330522', 'returned', 'customer disappeared'), 60 | (6, 'YQW672', '20091201', '20100117', 'shipped', 'repeat customer'), 61 | (7, 'DTR321', '29300419', '29330522', 'shipped', 'customer requested freight forwarding'), 62 | (3, 'BCQ858', '23170318', '23170329', 'shipped', 'customer prefers open-source software'); 63 | 64 | INSERT INTO OrderItems ( OrderID, ProductID, Quantity, UnitPrice, Discount, Notes ) 65 | VALUES 66 | (1, 1, 2, 24.99, 0.00, 'handle with care'), 67 | (1, 2, 1, 79.99, 2.38, 'keep away from magnetic fields'), 68 | (1, 3, 2, 2499.99, 191.17, 'avoid exposure to light'), 69 | (2, 5, 1, 14.99, 0.00, 'open source software'), 70 | (2, 7, 1, 3.49, 0.91, 'exceedingly rare'), 71 | (3, 11, 4, 47.89, 0.88, 'high-demand product'), 72 | (3, 10, 7, 399999.95, 24999.95, 'high gravity'), 73 | (5, 2, 2, 79.99, 2.17, 'customer transitioning from slide rules to software'), 74 | (5, 6, 1, 4.49, 0.00, 'heavy Scoville Units'), 75 | (5, 5, 1, 14.99, 1.89, 'financial planning'), 76 | (6, 10, 2, 399999.95, 25000.00, 'aircraft construction'), 77 | (6, 7, 1, 3.49, 0.00, 'Test for magnetism before use'); 78 | 79 | INSERT INTO Payments ( OrderID, PaymentDate, PaymentType, PaymentRef, Amount, Notes ) 80 | VALUES 81 | (1, '20170221', 'credit card', 'W2GHA4', 100.00, 'payment received' ), 82 | (1, '20170301', 'credit card', 'I3G2V7', 75.00, 'payment received' ), 83 | (2, '20100105', 'check', 'SRT2Z7', 83.50, 'partial payment'), 84 | (2, '20100222', 'cash', 'DET281', 12.79, 'partial payment'); -------------------------------------------------------------------------------- /SCRIPTS/SQL SERVER SCRIPTS/SQL_SERVER_create_data.sql: -------------------------------------------------------------------------------- 1 | USE [PACKT_ONLINE_SHOP] 2 | GO 3 | 4 | INSERT INTO Customers ( FirstName, MiddleName, LastName, [Address], Email, Phone, Notes ) 5 | VALUES 6 | ('Joe', 'Greg', 'Smith', '2356 Elm St.', 'joesmith@sfghwert.com', '(310) 555-1212', 'A note'), 7 | ('Grace', 'Murray', 'Hopper', '123 Compilation Street', 'gmhopper@ftyuw46.com', '(818) 555-3678', 'Compiler pioneer'), 8 | ('Ada', NULL, 'Lovelace', '22 Algorithm Way', 'adalovelace@fgjw54af.gov', '(717) 555-3457', 'First software engineer'), 9 | ('Joseph', 'Force', 'Crater', '1313 Mockingbird Lane', 'judgecrater@ev56gfwrty.com', '(212) 555-5678', 'Might undisappear any minute . . .'), 10 | ('Jacqueline', 'Jackie', 'Cochran', '1701 Flightspeed Avenue', 'jackiecochrane@jryuwp8qe4w.gov', '(717) 555-3457', 'Research aviator'), 11 | ('William', NULL, 'Shakespeare', '456 Old Globe', 'wshakespeare@dyuioety4.gov', '(213) 555-3421', 'Playwright'), 12 | ('Nellie', NULL, 'Bly', '614 Printing Press Way', 'nellie@fthw45asdgf.com', '(213) 555-8523', 'Investigative Journalist'), 13 | ('Yuri', 'Alekseyevich', 'Gagarin', '1 Ad Astra', 'yuri@rheysdagf.edu', '(310) 555-5462', 'First human to space'), 14 | (NULL, 'Paul', 'Jones', '126 Bonhomme Richard Ave.', 'jpjones@bonhommerichard.edu', '(216) 555-6232', 'Admiral'), 15 | (NULL, 'Al', 'Smith', '1818 Eratosthenes Blvd.', 'alsmith@dytsdrg.edu', '(345) 555-5434', 'Writer'), 16 | (NULL, NULL, 'Pythagoras', '32 Hypotenuse Way', 'pythagoras@sdrg.edu', '(260) 555-3461', 'Mathematician'), 17 | (NULL, NULL, 'Bleriot', '55 Rue Montgolfier', 'bleriot@wtrasf.gov', '(818) 555-3562', 'Pilot'), 18 | ('Aristotle', NULL, NULL, '32 Parthenon Way', 'aristotle@ertyasdf.edu', '(310) 555-9182', 'Scholar'), 19 | ('Cicero', NULL, NULL, '25 Appian Way', 'Cicero@ghyu45y.edu', '(310) 555-0822', 'Orator'), 20 | ('Srinivasa', NULL, 'Ramanujan', '123 Bernoulli Number Drive', 'srinivasa@imaginarynumber.edu', '(211) 555-1111', 'Sharp Mathematician'), 21 | ('Orville', NULL, 'Wright', '80 Bicycle Lane', 'owright@sdg98.edu', '(211) 555-4444', 'First pilot') 22 | 23 | 24 | INSERT INTO Suppliers ( SupplierName, Country, [Address], PhoneNumber, ContactPerson, Notes ) 25 | VALUES 26 | ('Acme Systems', 'Switzerland', '123 Capital Drive', '(818) 555-3456', 'Smith Johns', 'spaceship company'), 27 | ('Amalgamated Software', 'Antarctica', '771 South Pole Ave.', '(415) 555-2347', 'Smith Johns', 'software company'), 28 | ('AWT', 'USA', '123 Rockefeller Drive', '(212) 555-3783', 'Trippe Juan', 'airline'), 29 | ('Consolidated Products', 'Canada', '771 Winnipeg Way', '(109) 555-4721', 'Allen Wight', 'food and aluminum company'), 30 | ('CHOAM', 'Atlantis', '123 Atlantean Way', '(213) 555-7567', 'Horace Greeley', 'transport services company'), 31 | ('Sliderule Computers', 'USA', '22 Prediction Ave.', '(310) 555-3456', 'Adam Osborne', 'Computer company') 32 | 33 | 34 | INSERT INTO ProductCategories ( ProductCategoryName, Notes ) 35 | VALUES 36 | ('condiments', 'melange, spices of all types and flavorings' ), 37 | ('tools', 'automotive, aviation, medical, and software repair / maintenance devices ' ), 38 | ('food', 'food products for humans and non-humans' ), 39 | ('airships', 'lighter-than-air aircraft' ), 40 | ('software', 'program products for execution on / by computers' ), 41 | ('books', 'bound, multi-page printed material' ), 42 | ('horse-drawn carriages', 'wheeled vehicles pulled by plant-eating non-human animals') 43 | 44 | INSERT INTO Products ( ProductCategoryID, SupplierID, ProductName, ProductImage, NetRetailPrice, AvailableQuantity, WholesalePrice, UnitKGWeight, Notes ) 45 | VALUES 46 | (5, 2, 'Calculatre', NULL, $24.99, 100, $17.99, 1, 'calculation application'), 47 | (5, 5, 'Penwrite', NULL, $79.99, 27, $49.99, 2, 'word processing product'), 48 | (1, 6, 'Vortex Generator', NULL, $2499.99, 1000, $1999.99, 0.01, 'space engine component'), 49 | (1, 6, 'The Gourmet Crockpot', NULL, $24.99, 72, $19.99, 1.63, 'cookbook'), 50 | (1, 6, 'Government Accounting', NULL, $14.99, 26, $9.99, 1.22, 'government accounting book'), 51 | (3, 6, 'habanero peppers', NULL, $4.49, 189, $2.99, 0.009, 'hot peppers'), 52 | (2, 1, '10-mm socket wrench', NULL, $3.49, 39, $1.89, 0.018, 'important tool'), 53 | (3, 4, 'tomato sauce', NULL, $1.19, 1509, $0.89, 0.232, 'bottled in glass'), 54 | (1, 6, 'pure vanilla', NULL, $10.39, 1509, $7.89, 0.032, 'high-quality vanilla'), 55 | (3, 2, 'keyboard wrench', NULL, $399999.95, 6128, $149999.99, 521.38, 'handle with care'), 56 | (2, 1, 'power cell', NULL, $47.89, 2346, $29.99, 0.298, 'ten amp-hours per cell') 57 | 58 | INSERT INTO Orders ( CustomerID, OrderNumber, OrderDate, ShipmentDate, OrderStatus, Notes ) 59 | VALUES 60 | (2, 'ABC123', '20170302', '20170212', 'shipped', 'shipped on time'), 61 | (3, 'BCQ857', '23170307', '23170308', 'pending', 'for appropriate products, fully charge all power cells before packing'), 62 | (4, 'RST321', '19300419', '19330522', 'returned', 'customer disappeared'), 63 | (6, 'YQW672', '20091201', '20100117', 'shipped', 'repeat customer'), 64 | (7, 'DTR321', '29300419', '29330522', 'shipped', 'customer requested freight forwarding'), 65 | (3, 'BCQ858', '23170318', '23170329', 'shipped', 'customer prefers open-source software') 66 | 67 | INSERT INTO OrderItems ( OrderID, ProductID, Quantity, UnitPrice, Discount, Notes ) 68 | VALUES 69 | (1, 1, 2, $24.99, $0.00, 'handle with care'), 70 | (1, 2, 1, $79.99, $2.38, 'keep away from magnetic fields'), 71 | (1, 3, 2, $2499.99, $191.17, 'avoid exposure to light'), 72 | (2, 5, 1, $14.99, $0.00, 'open source software'), 73 | (2, 7, 1, $3.49, $0.91, 'exceedingly rare'), 74 | (3, 11, 4, $47.89, $0.88, 'high-demand product'), 75 | (3, 10, 7, $399999.95, $24999.95, 'high gravity'), 76 | (5, 2, 2, $79.99, $2.17, 'customer transitioning from slide rules to software'), 77 | (5, 6, 1, $4.49, $0.00, 'heavy Scoville Units'), 78 | (5, 5, 1, $14.99, $1.89, 'financial planning'), 79 | (6, 10, 2, $399999.95, $25000.00, 'aircraft construction'), 80 | (6, 7, 1, $3.49, $0.00, 'Test for magnetism before use') 81 | 82 | INSERT INTO Payments ( OrderID, PaymentDate, PaymentType, PaymentRef, Amount, Notes ) 83 | VALUES 84 | (1, '20170221', 'credit card', 'W2GHA4', $100.00, 'payment received' ), 85 | (1, '20170301', 'credit card', 'I3G2V7', $75.00, 'payment received' ), 86 | (2, '20100105', 'check', 'SRT2Z7', $83.50, 'partial payment'), 87 | (2, '20100222', 'cash', 'DET281', $12.79, 'partial payment') -------------------------------------------------------------------------------- /Chapter07/Chapter 7 Activity.sql: -------------------------------------------------------------------------------- 1 | /****** Introduction To SQL Chapter SEVEN Scripts ******/ 2 | 3 | /****** Aggregate Functions ******/ 4 | 5 | SELECT COUNT(CustomerID) 6 | FROM CUSTOMERS; 7 | 8 | 9 | SELECT COUNT(Notes) 10 | FROM CUSTOMERS; 11 | 12 | 13 | SELECT COUNT(*) 14 | FROM CUSTOMERS; 15 | 16 | 17 | SELECT SUM(AMOUNT) 18 | FROM PAYMENTS 19 | 20 | 21 | SELECT SUM(AMOUNT) 22 | FROM PAYMENTS 23 | WHERE AMOUNT>50 24 | 25 | 26 | SELECT AVG(AMOUNT) 27 | FROM PAYMENTS 28 | 29 | 30 | SELECT MAX(Amount) 31 | FROM PAYMENTS 32 | 33 | 34 | /****** GROUPING ******/ 35 | 36 | 37 | SELECT PaymentType, SUM(Amount)as TotalAmount 38 | FROM Payments 39 | GROUP BY PaymentType 40 | 41 | 42 | SELECT paymentid ,PaymentType, SUM(Amount)as TotalAmount 43 | FROM Payments 44 | GROUP BY PaymentType,PaymentID 45 | 46 | /****** Using the Having Clause to narrow down results ******/ 47 | 48 | 49 | SELECT PaymentType, SUM(Amount)as TotalAmount 50 | FROM Payments 51 | GROUP BY PaymentType 52 | Having SUM(AMOUNT) > 50 53 | 54 | 55 | /****** Built In Value Functions ******/ 56 | 57 | 58 | 59 | 60 | /****** String Value Functions ******/ 61 | 62 | 63 | 64 | SELECT ASCII('A') 65 | 66 | 67 | Select CHAR(65) 68 | 69 | 70 | SELECT CHARINDEX('ck', 'Packt') AS MatchIndex; 71 | 72 | 73 | SELECT CHARINDEX('ck', 'Packt',3) AS MatchIndex; 74 | 75 | SELECT CONCAT ( 'Happy ', 'Birthday ', 11, '/', '25' ) AS Result; 76 | 77 | SELECT CONCAT_WS(',','1 Microsoft Way', NULL, NULL, 'Redmond', 'WA', 98052) AS Address; 78 | 79 | SELECT 'SQL' + ' is' + ' fun!'; 80 | 81 | SELECT SOUNDEX('Green'), SOUNDEX('Greene'), DIFFERENCE('Green','Greene'); 82 | 83 | 84 | SELECT SOUNDEX('Blotchet-Halls'), SOUNDEX('Greene'), DIFFERENCE('Blotchet-Halls', 'Greene'); 85 | 86 | 87 | DECLARE @d DATETIME = GETDATE(); 88 | SELECT FORMAT( @d, 'dd/MM/yyyy', 'en-US' ) AS 'DateTime Result' 89 | ,FORMAT(123456789,'###-##-####') AS 'Custom Number Result'; 90 | 91 | 92 | SELECT LEFT('abcdefg',2); 93 | 94 | 95 | SELECT DATALENGTH('PACKT'); 96 | 97 | 98 | 99 | DECLARE @v1 varchar(40), 100 | @v2 nvarchar(40); 101 | SELECT 102 | @v1 = 'Test of 22 characters ', 103 | @v2 = 'Test of 22 characters '; 104 | SELECT LEN(@v1) AS [varchar LEN] , DATALENGTH(@v1) AS [varchar DATALENGTH]; 105 | SELECT LEN(@v2) AS [nvarchar LEN], DATALENGTH(@v2) AS [nvarchar DATALENGTH]; 106 | 107 | 108 | SELECT LEN('PACKT'); 109 | 110 | SELECT LOWER('PACKT'); 111 | 112 | SELECT LTRIM(' Five spaces are at the beginning of this string.') 113 | 114 | 115 | SELECT NCHAR(100) 116 | 117 | 118 | SELECT PATINDEX('%ter%', 'interesting data'); 119 | 120 | SELECT PATINDEX('%en_ure%', 'please ensure the door is locked'); 121 | 122 | 123 | SELECT QUOTENAME('abc[]def'); 124 | 125 | 126 | SELECT REPLACE('abcdefghicde','cde','xxx'); 127 | 128 | 129 | SELECT REPLICATE('PACKT ',4) 130 | 131 | SELECT REVERSE(1234) AS Reversed ; 132 | 133 | 134 | SELECT REVERSE('PACKT'); 135 | 136 | SELECT RIGHT('PACKT',2); 137 | 138 | SELECT RTRIM('Removes trailing spaces. '); 139 | 140 | 141 | SELECT SOUNDEX ('Smith'), SOUNDEX ('Smythe'); 142 | 143 | SELECT CONCAT('PACKT',SPACE(3),'BOOK'); 144 | 145 | SELECT STR(123.45, 6, 1); 146 | 147 | 148 | SELECT STUFF('abcdef', 2, 3, 'ijklmn'); 149 | 150 | 151 | SELECT SUBSTRING('abcdef', 2, 3); 152 | 153 | SELECT TRANSLATE('2*[3+4]/{7-2}', '[]{}', '()()'); 154 | 155 | SELECT TRIM( ' test ') ; 156 | 157 | SELECT TRIM( '.,! ' FROM ' # test .') ; 158 | 159 | 160 | DECLARE @nstring nchar(12); 161 | SET @nstring = N'Åkergatan 24'; 162 | SELECT UNICODE(@nstring), NCHAR(UNICODE(@nstring)); 163 | 164 | 165 | 166 | SELECT UPPER('Packt') 167 | 168 | 169 | 170 | 171 | 172 | 173 | /****** Numeric Value Functions ******/ 174 | 175 | 176 | SELECT ABS(-1.0), ABS(0.0), ABS(1.0); 177 | 178 | 179 | SELECT ACOS(-1.0) 180 | 181 | 182 | SELECT ASIN(-1.0) 183 | 184 | 185 | 186 | SELECT ATAN(45.0) 187 | 188 | 189 | DECLARE @x float = 35.175643, @y float = 129.44; 190 | SELECT ATN2(@y, @x); 191 | 192 | 193 | 194 | 195 | SELECT CEILING($123.45), CEILING($-123.45), CEILING($0.0); 196 | 197 | 198 | 199 | DECLARE @x float = 45 200 | SELECT COS(@x) 201 | 202 | DECLARE @x float = 90 203 | SELECT COT(@x) 204 | 205 | 206 | 207 | SELECT DEGREES(5) 208 | 209 | 210 | DECLARE @x float = 10 211 | SELECT EXP(@x) 212 | 213 | 214 | SELECT FLOOR(123.45), FLOOR(-123.45), FLOOR($123.45); 215 | 216 | SELECT LOG (EXP (10)); 217 | 218 | DECLARE @x float = 145.175643 219 | SELECT log10(@x) 220 | 221 | 222 | SELECT PI(); 223 | 224 | SELECT POWER(4,2); 225 | 226 | SELECT RADIANS(180); 227 | 228 | 229 | SELECT RAND(100), RAND(), RAND() ; 230 | 231 | 232 | SELECT ROUND(123.9994, 3), ROUND(123.9995, 3); 233 | 234 | 235 | SELECT SIGN(-125), SIGN(0), SIGN(564); 236 | 237 | DECLARE @x float = 90 238 | SELECT SIN(@x) 239 | 240 | 241 | SELECT SQRT(4) 242 | 243 | 244 | 245 | SELECT SQUARE(4) 246 | 247 | 248 | 249 | DECLARE @x float = 90 250 | SELECT TAN(@x) 251 | 252 | 253 | 254 | /****** Date and Time Value Functions ******/ 255 | 256 | Select CURRENT_TIMESTAMP 257 | 258 | SELECT DATEADD(year,2, '20060731'); 259 | 260 | SELECT DATEDIFF(day, 261 | '2007-05-07 09:53:01.0376635', 262 | '2007-05-08 09:53:01.0376635'); 263 | 264 | SELECT DATEFROMPARTS ( 2010, 12, 31 ) 265 | 266 | 267 | SELECT DATEPART(week, '2007-04-21 ') 268 | 269 | SELECT DAY('2015-04-30 01:01:01.1234567'); 270 | 271 | SELECT GETDATE() 272 | 273 | 274 | SELECT GETUTCDATE() 275 | 276 | SELECT ISDATE('THIS IS NOT A DATE'),ISDATE('2019-08-31') 277 | 278 | SELECT MONTH('2007-04-30'); 279 | 280 | 281 | SELECT SYSDATETIME ( ) 282 | 283 | SELECT Year('2007-04-30'); 284 | 285 | 286 | 287 | /****** Conversion Functions ******/ 288 | 289 | SELECT CAST(25.65 AS int), CAST(25.65 AS varchar); 290 | 291 | SELECT Convert(int, 25.65), Convert(varchar, 25.65 ), CONVERT(nvarchar(30), GETDATE(), 109); 292 | 293 | SELECT PARSE('€345,98' AS money USING 'de-DE') AS Result 294 | 295 | SELECT PARSE('Monday, 13 December 2010' AS datetime2 USING 'en-US') AS Result; 296 | 297 | SELECT TRY_CAST('test' AS float) , TRY_CAST('12/31/2010' AS datetime2) 298 | 299 | SELECT TRY_CONVERT(float, 'test') , TRY_CONVERT(datetime2, '12/31/2010') 300 | 301 | 302 | SELECT TRY_PARSE('Jabberwokkie' AS datetime2 USING 'en-US'),TRY_PARSE('01/01/2011' AS datetime2) 303 | 304 | 305 | /****** Activity Solutions ******/ 306 | 307 | 308 | Select OrderItems.OrderID, Sum(Quantity * ( OrderItems.UnitPrice - (OrderItems.Discount * OrderItems.UnitPrice ) )) as 'Total Amount After Discount', Count(OrderID) as'Count Of Line Items in Each OrderID' 309 | from OrderItems 310 | 311 | Group By OrderID 312 | 313 | 314 | Select UPPER(CONCAT(FIRSTNAME,' ',LASTNAME,'-',LEFT(Phone,5))), 315 | YEAR(GETDATE()) as 'Year', 316 | Month(GETDATE())as 'Month', 317 | DAY(getdate())as 'Day' 318 | 319 | from customers 320 | 321 | -------------------------------------------------------------------------------- /Chapter09/Chapter 9 Scripts.sql: -------------------------------------------------------------------------------- 1 | /****** Introduction To SQL Chapter NINE Scripts ******/ 2 | 3 | /****** SUBQUERIES ******/ 4 | 5 | USE packt_online_shop; 6 | 7 | SELECT Products.ProductID, Products.ProductName, 8 | Products.ProductCategoryID 9 | FROM Products LEFT OUTER JOIN 10 | OrderItems 11 | ON Products.ProductID = OrderItems.ProductID 12 | WHERE OrderItems.ProductID IS NULL 13 | ORDER BY Products.ProductID; 14 | 15 | 16 | USE packt_online_shop; 17 | 18 | SELECT Products.ProductID, Products.ProductName, 19 | Products.ProductCategoryID 20 | FROM Products INNER JOIN OrderItems 21 | ON Products.ProductID = OrderItems.ProductID 22 | WHERE OrderItems.ProductID IS NULL 23 | ORDER BY Products.ProductID; 24 | 25 | 26 | USE packt_online_shop; 27 | 28 | SELECT Products.ProductID, Products.ProductName, 29 | Products.ProductCategoryID 30 | FROM Products 31 | WHERE Products.ProductID NOT IN 32 | (SELECT ProductID FROM OrderItems) 33 | ORDER BY Products.ProductID; 34 | 35 | 36 | SELECT ProductID FROM OrderItems 37 | 38 | 39 | /****** EXERCISE 1 ******/ 40 | 41 | -- STEP 1: 42 | 43 | USE packt_online_shop; 44 | 45 | SELECT OrderID FROM ORDERITEMS; 46 | 47 | -- STEP 2: 48 | 49 | USE packt_online_shop; 50 | SELECT O.OrderID 51 | FROM Orders O 52 | 53 | -- STEP 3: 54 | 55 | USE packt_online_shop; 56 | 57 | SELECT O.OrderID 58 | FROM Orders O 59 | WHERE O.OrderID NOT IN 60 | 61 | (SELECT OrderID FROM ORDERITEMS) 62 | 63 | ORDER BY O.OrderID; 64 | 65 | 66 | /****** ACTIVITY 1 SOLUTION ******/ 67 | 68 | USE packt_online_shop; 69 | 70 | SELECT PC.ProductCategoryName 71 | FROM ProductCategories PC 72 | WHERE ProductCategoryID IN 73 | 74 | ( SELECT ProductCategoryID 75 | FROM Products 76 | WHERE ProductName = 'habanero peppers' ); 77 | 78 | 79 | /****** CASE STATEMENTS ******/ 80 | 81 | USE packt_online_shop; 82 | 83 | SELECT ProductName, WholesalePrice, NetRetailPrice, 84 | 'Price Point' AS 'Price Point', UnitKGWeight 85 | FROM products 86 | ORDER BY ProductName; 87 | 88 | 89 | USE packt_online_shop; 90 | 91 | SELECT ProductName, WholesalePrice, NetRetailPrice, 92 | CASE 93 | WHEN NetRetailPrice <= 24.99 THEN 'Cheap' 94 | WHEN NetRetailPrice > 24.99 AND 95 | NetRetailPrice <= 79.99 THEN 'Mid-price' 96 | WHEN NetRetailPrice > 79.99 AND 97 | NetRetailPrice <= 2499.99 THEN 'Expensive' 98 | ELSE 'Very Expensive' 99 | END AS 'Price Point', 100 | UnitKGWeight 101 | FROM products 102 | ORDER BY ProductName; 103 | 104 | 105 | /****** EXERCISE 1 ******/ 106 | 107 | -- STEP 1: 108 | 109 | USE packt_online_shop; 110 | 111 | SELECT ProductName, NetRetailPrice, UnitKGWeight 112 | FROM products; 113 | 114 | -- STEP 2: 115 | 116 | USE packt_online_shop; 117 | 118 | SELECT ProductName, NetRetailPrice, UnitKGWeight, 119 | CASE 120 | WHEN (NetRetailPrice * UnitKGWeight) <= 1.0 THEN 'Cheap' 121 | END AS 'Shipping Cost' 122 | FROM products 123 | 124 | -- STEP 3: 125 | 126 | USE packt_online_shop; 127 | 128 | SELECT ProductName, NetRetailPrice, UnitKGWeight, 129 | CASE 130 | WHEN (NetRetailPrice * UnitKGWeight) <= 1.0 THEN 'Cheap' 131 | WHEN (NetRetailPrice * UnitKGWeight) > 1.0 AND 132 | (NetRetailPrice * UnitKGWeight) <= 35.00 THEN 'Mid-price' 133 | WHEN (NetRetailPrice * UnitKGWeight) > 35.00 AND 134 | (NetRetailPrice * UnitKGWeight) <= 100.00 THEN 'Expensive' 135 | ELSE 'Very Expensive' 136 | END AS 'Shipping Cost' 137 | FROM products; 138 | 139 | 140 | /****** ACTIVITY 2 SOLUTION ******/ 141 | 142 | USE packt_online_shop; 143 | 144 | SELECT OrderNumber, ShipmentDate, 145 | CASE 146 | WHEN ShipmentDate < ' 2010-12-10' THEN 'Past Shipment Date' 147 | WHEN ShipmentDate >= ' 2010-12-10' AND 148 | ShipmentDate < ' 2018-12-18' THEN 'Recent Shipment Date' 149 | ELSE 'Future Shipment Date' 150 | END AS 'Shipment Date Category' 151 | FROM Orders; 152 | 153 | 154 | /****** VIEWS ******/ 155 | 156 | USE packt_online_shop; 157 | 158 | SELECT CONCAT(customers.FirstName, ' ', customers.LastName) AS 'CustomerName', 159 | orders.OrderDate, products.ProductName 160 | FROM customers INNER JOIN orders ON 161 | customers.CustomerID = orders.CustomerID 162 | INNER JOIN orderitems ON 163 | orders.OrderID = orderitems.OrderID 164 | INNER JOIN products ON 165 | orderitems.ProductID = products.ProductID; 166 | 167 | 168 | USE packt_online_shop; 169 | GO -- Include for SQL Server; remove for MySQL 170 | 171 | 172 | CREATE VIEW CUSTOMER_PRODUCT_VIEW 173 | 174 | AS 175 | 176 | SELECT CONCAT(customers.FirstName, ' ', customers.LastName) AS 'CustomerName', 177 | orders.OrderDate, products.ProductName 178 | FROM customers INNER JOIN orders ON 179 | customers.CustomerID = orders.CustomerID 180 | INNER JOIN orderitems ON 181 | orders.OrderID = orderitems.OrderID 182 | INNER JOIN products ON 183 | orderitems.ProductID = products.ProductID; 184 | 185 | 186 | SELECT CustomerName, OrderDate, ProductName 187 | FROM customer_product_view; 188 | 189 | 190 | /****** EXERCISE 3 ******/ 191 | 192 | -- STEP 1: 193 | 194 | USE PACKT_ONLINE_SHOP; 195 | 196 | SELECT customers.CustomerID, orders.OrderDate, 197 | products.ProductID, products.ProductName, 198 | orderitems.Quantity * orderitems.UnitPrice AS 199 | 'PerProductSpending' 200 | FROM customers INNER JOIN orders ON 201 | customers.CustomerID = orders.CustomerID 202 | INNER JOIN orderitems ON 203 | orders.OrderID = orderitems.OrderID 204 | INNER JOIN products ON 205 | orderitems.ProductID = products.ProductID 206 | 207 | 208 | -- STEP 2: 209 | 210 | USE PACKT_ONLINE_SHOP; 211 | 212 | CREATE VIEW PACKT_VIEW_1 213 | 214 | AS 215 | 216 | SELECT customers.CustomerID, orders.OrderDate, 217 | products.ProductID, products.ProductName, 218 | orderitems.Quantity * orderitems.UnitPrice AS 219 | 'PerProductSpending' 220 | FROM customers INNER JOIN orders ON 221 | customers.CustomerID = orders.CustomerID 222 | INNER JOIN orderitems ON 223 | orders.OrderID = orderitems.OrderID 224 | INNER JOIN products ON 225 | orderitems.ProductID = products.ProductID 226 | 227 | 228 | -- STEP 3: 229 | 230 | USE PACKT_ONLINE_SHOP; 231 | 232 | GO -- Include for SQL Server; don't include for MySQL 233 | 234 | CREATE VIEW PACKT_VIEW_1 235 | 236 | AS 237 | 238 | SELECT customers.CustomerID, orders.OrderDate, 239 | products.ProductID, products.ProductName, 240 | orderitems.Quantity * orderitems.UnitPrice AS 241 | 'PerProductSpending' 242 | FROM customers INNER JOIN orders ON 243 | customers.CustomerID = orders.CustomerID 244 | INNER JOIN orderitems ON 245 | orders.OrderID = orderitems.OrderID 246 | INNER JOIN products ON 247 | orderitems.ProductID = products.ProductID 248 | 249 | 250 | -- STEP 4: 251 | 252 | USE PACKT_ONLINE_SHOP; 253 | 254 | SELECT CustomerID, OrderDate, ProductID, ProductName, 255 | PerProductSpending 256 | FROM PACKT_VIEW_1 257 | WHERE PerProductSpending > 14.99; 258 | 259 | 260 | /****** ACTIVITY 3 SOLUTION ******/ 261 | 262 | USE packt_online_shop; 263 | 264 | CREATE VIEW Atreides_Sales_View AS 265 | 266 | SELECT OI.OrderID, OI.ProductID, OI.Quantity, OI.UnitPrice, 267 | (OI.Quantity * OI.UnitPrice) AS 'subtotal', 268 | CASE 269 | WHEN (OI.Quantity * OI.UnitPrice) < 25.00 THEN 'Small' 270 | WHEN (OI.Quantity * OI.UnitPrice) <= 79.99 THEN 'Medium' 271 | ELSE 'Large' 272 | END AS 'Subtotal Category' 273 | FROM OrderItems OI INNER JOIN 274 | Orders O ON OI.OrderID = O.OrderID 275 | WHERE O.CustomerID IN 276 | ( SELECT CustomerID 277 | FROM Customers 278 | WHERE LastName = 'Atreides' ); 279 | -------------------------------------------------------------------------------- /Chapter03/Chapter 3: -------------------------------------------------------------------------------- 1 | Example 1: 2 | 3 | --How to define a foreign key on CUSTOMER_ID of ORDERS table referring to CUSTOMERID of CUSTOMERS table. 4 | 5 | DROP DATABASE IF EXISTS PACKT_ONLINE_SHOP; 6 | CREATE DATABASE IF NOT EXISTS PACKT_ONLINE_SHOP; 7 | USE PACKT_ONLINE_SHOP; 8 | CREATE TABLE Customers 9 | ( 10 | CustomerID INT NOT NULL AUTO_INCREMENT, 11 | FirstName CHAR(50) NOT NULL, 12 | LastName CHAR(50) NOT NULL, 13 | Address CHAR(250) NULL, 14 | Email CHAR(200) NULL, 15 | Phone CHAR(50) NULL, 16 | Notes VARCHAR(750) NULL, 17 | BalanceNotes VARCHAR(750) NULL, 18 | PRIMARY KEY (CustomerID) 19 | ); 20 | /* 21 | Note: 22 | A foreign key always refer to a primary key. 23 | A table can have multiple foreign key 24 | Insert command only operates on those rows of the CHILD table for which corresponding rows exist in the PARENT table 25 | Delete command only operates on the rows from the PARENT table for which there are no corresponding records in the CHILD table. 26 | */ 27 | 28 | CREATE TABLE Orders 29 | ( 30 | OrderID INT NOT NULL AUTO_INCREMENT, 31 | CustomerID INT NOT NULL, 32 | OrderNumber CHAR(50) NOT NULL, 33 | OrderDate DATETIME NOT NULL, 34 | ShipmentDate DATETIME NULL, 35 | OrderStatus CHAR(10) NULL, 36 | Notes VARCHAR(750) NULL, 37 | PRIMARY KEY (OrderID), 38 | FOREIGN KEY FK_Customer_CusomterID(CustomerID) REFERENCES Customers(CustomerID) 39 | ); 40 | 41 | Example 2: 42 | 43 | --Create OrderItems table and add define a foreign key on PRODUCTID of OrderItems table referring to PRODUCTID of ORDERS table. 44 | 45 | CREATE TABLE OrderItems 46 | ( 47 | OrderItemID INT NOT NULL AUTO_INCREMENT, 48 | OrderID INT NOT NULL, 49 | ProductID INT NOT NULL, 50 | Quantity INT NOT NULL, 51 | UnitPrice DECIMAL(10, 2) NOT NULL, 52 | Discount DECIMAL(10, 2) NULL, 53 | Notes VARCHAR(750) NULL, 54 | PRIMARY KEY (OrderItemID) 55 | ); 56 | 57 | ALTER TABLE OrderItems 58 | ADD FOREIGN KEY (ProductID) REFERENCES Products(ProductID); 59 | 60 | Example 3: 61 | 62 | --To drop a foreign key ProductID from OrderItems, you would use the ALTER TABLE statement, like so: 63 | --In the context of our example, the statement would be: 64 | 65 | ALTER TABLE OrderItems 66 | DROP FOREIGN KEY ProductID 67 | 68 | Example 4 69 | 70 | /* 71 | How to present employee and department data in two tables and build the relationship between Department and employee table. 72 | 73 | Create DEPARTMENT table with the following data 74 | ColumnName DataType Size Key 75 | DeptNo NUMBER Primary Key 76 | DName VARCHAR2 20 UNIQUE and NOT NULL 77 | Dlocation VARCHAR2(30) UNIQUE and NOT NULL 78 | */ 79 | CREATE TABLE DEPARTMENT 80 | ( 81 | DeptNo NUMBER PRIMARY KEY, 82 | Dname VARCHAR2(30) UNIQUE NOT NULL, 83 | Dlocation VARCHAR2(30) UNIQUE NOT NULL 84 | ) 85 | /* 86 | Create EMPLOYEE table with the following data 87 | ColumnName DataType Size Key 88 | eNo CHAR 4 PRIMARY KEY 89 | eName VARCHAR2 30 NOT NULL 90 | Job VARCHAR2 30 91 | MANAGER CHAR 4 92 | JDate TIMESTAMP NOT NULL 93 | Gender CHAR 1 'M' OR 'F' 94 | Salary NUMBER 8,2 DEFAULT 0 95 | Comission NUMBER 8,2 DEFAULT 0 96 | Deptno NUMBER 2 FOREIGN KEY REFERENCES DEPARTMENT TABLE, DEPTNO column 97 | */ 98 | CREATE TABLE EMPLOYEE 99 | ( 100 | eNo CHAR(4) PRIMARY KEY, 101 | eName VARCHAR2(30) NOT NULL, 102 | Job VARCHAR2(30) NOT NULL, 103 | MANAGER CHAR(4), 104 | JDate TIMESTAMP NOT NULL, 105 | Gender CHAR(1) CONSTRAINT Gender_CHK GENDER('M','F'), 106 | Salary NUMBER(8,2) DEFAULT 0, 107 | Comission NUMBER(8,2) DEFAULT 0, 108 | Deptno NUMBER(2) FOREIGN KEY REFERENCES DEPARTMENT(Deptno) 109 | ) 110 | 111 | 112 | /* 113 | 114 | Activity Section 115 | 116 | An example of FOREIGN KEY constraint using ON DELETECASCADE option is as follows 117 | 118 | Create the Customers(Parent) table 119 | */ 120 | 121 | 122 | CREATE TABLE customers 123 | ( 124 | customerid INT NOT NULL IDENTITY(1, 1), 125 | firstname CHAR(50) NULL, 126 | middlename CHAR(50) NULL, 127 | lastname CHAR(50) NULL, 128 | address CHAR(250) NULL, 129 | email CHAR(200) NULL, 130 | phone CHAR(50) NULL, 131 | notes VARCHAR(750) NULL, 132 | balancenotes VARCHAR(750) NULL, 133 | PRIMARY KEY (customerid) 134 | ); 135 | 136 | ----Create the Orders(Child) table 137 | 138 | CREATE TABLE orders 139 | ( 140 | orderid INT NOT NULL IDENTITY(1, 1), 141 | customerid INT NOT NULL, 142 | ordernumber CHAR(50) NOT NULL, 143 | orderdate DATETIME NOT NULL, 144 | shipmentdate DATETIME NULL, 145 | orderstatus CHAR(10) NULL, 146 | notes VARCHAR(750) NULL, 147 | PRIMARY KEY (orderid), 148 | FOREIGN KEY (customerid) REFERENCES customers (customerid) ON DELETE 149 | CASCADE 150 | ); 151 | 152 | 153 | ----Insert rows into the Customer and Orders tables 154 | 155 | INSERT INTO customers 156 | (firstname, 157 | middlename, 158 | lastname, 159 | address, 160 | email, 161 | phone, 162 | notes) 163 | VALUES ('Joe', 164 | 'Greg', 165 | 'Doaks', 166 | '2356 Elm St.', 167 | 'joedoaks@sfghwert.com', 168 | '(310) 555-1212', 169 | 'A note'), 170 | ('Paul', 171 | 'Muad-Dib', 172 | 'Atreides', 173 | '123 Caladan Drive', 174 | 'patreides@sietchtabr.com', 175 | '(818) 555-3678', 176 | 'Outworlder, now a Fremen'), 177 | ('Mr.', 178 | NULL, 179 | 'Spock', 180 | '1701 Enterprise Drive', 181 | 'mrspock@NCC1701Enterprise.gov', 182 | '(717) 555-3457', 183 | 'Perceptive naval and science officer'), 184 | ('Joseph', 185 | 'Force', 186 | 'Crater', 187 | '1313 Mockingbird Lane', 188 | 'judgecrater@e56gfwrty.com', 189 | '(212) 555-5678', 190 | 'Might undisappear any minute . . .'), 191 | ('James', 192 | 'Tiberias', 193 | 'Kirk', 194 | '1701 Enterprise Drive', 195 | 'jtkirk@NCC1701Enterprise.gov', 196 | '(717) 555-3457', 197 | 'Naval combat veteran'), 198 | ('Luke', 199 | NULL, 200 | 'Skywalker', 201 | '456 Tosche Station', 202 | 'lskywalker@moseisley.gov', 203 | '(213) 555-3421', 204 | 'Pilot and mystic'), 205 | ('Chew', 206 | NULL, 207 | 'Bacca', 208 | 'Docking Bay 94, Kashyyyk', 209 | 'chewbacca@rebelalliance.edu', 210 | '(213) 555-8523', 211 | 'Executive Officer, Millennium Falcon'), 212 | ('Leto', 213 | 'II', 214 | 'Atreides', 215 | '1870 Arrakeen Ct.', 216 | 'latreides@arrakeen.org', 217 | '(310) 555-5462', 218 | 'Spice dealer'), 219 | (NULL, 220 | 'Paul', 221 | 'Jones', 222 | '126 Bonhomme Richard Ave.', 223 | 'jpjones@bonhommerichard.edu', 224 | '(216) 555-6232', 225 | 'Admiral'), 226 | (NULL, 227 | 'Han', 228 | 'Solo', 229 | '6136 Yavin St.', 230 | 'hsolo@dagobah.edu', 231 | '(345) 555-5434', 232 | 'Freighter Pilot'), 233 | (NULL, 234 | NULL, 235 | 'Gordon', 236 | '21 Mars Drive', 237 | 'Gordon@flashgordon.edu', 238 | '(260) 555-3461', 239 | 'Pilot'), 240 | (NULL, 241 | NULL, 242 | 'Zarkov', 243 | '55 Mongo Way', 244 | 'zarkov@mingofmongo.gov', 245 | '(818) 555-3562', 246 | 'Physics Researcher'), 247 | ('Gandalf', 248 | NULL, 249 | NULL, 250 | '18 Middle Earth Ave.', 251 | 'gan@dalf.gov', 252 | '(310) 555-9182', 253 | 'Wizard'), 254 | ('Klaatu', 255 | NULL, 256 | NULL, 257 | '33 Nikto Way', 258 | 'klaatu@klaatubaradanikto.edu', 259 | '(310) 555-0822', 260 | 'Droid'), 261 | ('Master', 262 | NULL, 263 | 'Yoda', 264 | '1818 Coruscant', 265 | 'yoda@coruscant.edu', 266 | '(211) 555-1111', 267 | 'Jedi Master'), 268 | ('QuiGon', 269 | NULL, 270 | 'Jinn', 271 | '3547 Coruscant', 272 | 'quigon@oldglobe.edu', 273 | '(211) 555-4444', 274 | 'Jedi Master'); 275 | 276 | INSERT INTO orders 277 | (customerid, 278 | ordernumber, 279 | orderdate, 280 | shipmentdate, 281 | orderstatus, 282 | notes) 283 | VALUES (2, 284 | 'ABC123', 285 | '20170302', 286 | '20170212', 287 | 'shipped', 288 | 'shipped on time'), 289 | (3, 290 | 'BCQ857', 291 | '23170307', 292 | '23170308', 293 | 'pending', 294 | 'for appropriate products, fully charge all power cells before packing'), 295 | (4, 296 | 'RST321', 297 | '19300419', 298 | '19330522', 299 | 'returned', 300 | 'customer disappeared'), 301 | (6, 302 | 'YQW672', 303 | '20091201', 304 | '20100117', 305 | 'shipped', 306 | 'repeat customer'), 307 | (7, 308 | 'DTR321', 309 | '29300419', 310 | '29330522', 311 | 'shipped', 312 | 'customer requested freight forwarding'), 313 | (3, 314 | 'BCQ858', 315 | '23170318', 316 | '23170329', 317 | 'shipped', 318 | 'customer prefers open-source software'); 319 | 320 | --Find the customer who is placed more than one orders 321 | 322 | SELECT o.customerid, 323 | Count(*) OrderCnt 324 | FROM customers c 325 | INNER JOIN orders o 326 | ON c.customerid = o.customerid 327 | GROUP BY o.customerid 328 | HAVING Count(*) > 1 329 | 330 | -- Fetch the details of customer and order for the customer id =3 331 | SELECT * 332 | FROM customers 333 | WHERE customerid = 3 334 | 335 | SELECT * 336 | FROM orders 337 | WHERE customerid = 3 338 | 339 | -- Delete the rows from the parent table customers. On use of ON DELETE CASCADE, we can see the deletion of rows from 340 | -- child table orders 341 | 342 | DELETE FROM customers 343 | WHERE customerid = 3 344 | 345 | 346 | -- Verify the customer and order for the customer id =3 . You'll see that records are deleted automatically from the child table 347 | 348 | SELECT * 349 | FROM customers 350 | WHERE customerid = 3 351 | 352 | SELECT * 353 | FROM orders 354 | WHERE customerid = 3 355 | -------------------------------------------------------------------------------- /Chapter10/Chapter 10 Activity.sql: -------------------------------------------------------------------------------- 1 | /****** Introduction To SQL Chapter TEN Scripts ******/ 2 | 3 | 4 | /****** PROGRAMMING FOR SQL PRODUCTS - THE BASICS ******/ 5 | 6 | -- SQL SERVER: 7 | 8 | DECLARE @var1 INTEGER -- 1. Declare variable @var1 as an INTEGER 9 | 10 | SELECT @var1 -- 2. Output the value of @var1 11 | 12 | SET @var1 = 3 -- 3. Set @var1 to 3 13 | 14 | SELECT @var1 -- 4. Output the value of @var1 15 | 16 | SET @var1 = @var1-7 -- 5. Subtract 7 from @var1 17 | 18 | SELECT @var1 -- 6. Output the value of @var1 19 | 20 | SET @var1 += 5 -- 7. Add 5 to @var1 21 | 22 | SELECT @var1 -- 8. Output the value of @var1 23 | 24 | 25 | -- MySQL: 26 | 27 | SET @var1 = NULL; -- 1. Declare variable @var1 as an INTEGER 28 | 29 | SELECT @var1; -- 2. Output the value of @var1 30 | 31 | SET @var1 = 3; -- 3. Set @var1 to 3 32 | 33 | SELECT @var1; -- 4. Output the value of @var1 34 | 35 | SET @var1 = @var1-7; -- 5. Subtract 7 from @var1 36 | 37 | SELECT @var1; -- 6. Output the value of @var1 38 | 39 | SET @var1 = @var1 + 5; -- 7. Add 5 to @var1 40 | 41 | SELECT @var1; -- 8. Output the value of @var1 42 | 43 | 44 | /****** STORED PROCEDURES ******/ 45 | 46 | USE packt_online_shop; 47 | 48 | SELECT ProductName, WholesalePrice, NetRetailPrice, 49 | CASE 50 | WHEN NetRetailPrice <= 24.99 THEN 'Cheap' 51 | WHEN NetRetailPrice > 24.99 AND 52 | NetRetailPrice <= 79.99 THEN 'Mid-price' 53 | WHEN NetRetailPrice > 79.99 AND 54 | NetRetailPrice <= 2499.99 THEN 'Expensive' 55 | ELSE 'Very Expensive' 56 | 57 | END AS 'Price Point', 58 | UnitKGWeight 59 | FROM products 60 | ORDER BY ProductName; 61 | 62 | 63 | CREATE PROCEDURE spFilterProductsByNRP 64 | 65 | @priceLevel float 66 | 67 | AS 68 | 69 | -- to test: spFilterProductsByNRP 206.00 70 | 71 | SELECT ProductName, WholesalePrice, NetRetailPrice, 72 | CASE 73 | WHEN NetRetailPrice <= 24.99 THEN 'Cheap' 74 | WHEN NetRetailPrice > 24.99 AND 75 | NetRetailPrice <= 79.99 THEN 'Mid-price' 76 | WHEN NetRetailPrice > 79.99 AND 77 | NetRetailPrice <= 2499.99 THEN 'Expensive' 78 | ELSE 'Very Expensive' 79 | 80 | END AS 'Price Point', 81 | UnitKGWeight 82 | FROM products 83 | WHERE NetRetailPrice <= @priceLevel 84 | ORDER BY ProductName; 85 | 86 | 87 | /****** EXERCISE 1 ******/ 88 | 89 | -- SQL SERVER: 90 | 91 | CREATE PROCEDURE spCustomerOrders 92 | 93 | @orderDate Datetime 94 | 95 | AS 96 | 97 | -- to test: spCustomerOrders 'January 2, 2010' 98 | 99 | SELECT C.FirstName + ' ' + C.LastName as 'Customer Name', 100 | O.OrderNumber, O.OrderDate 101 | 102 | FROM orders O INNER JOIN customers C ON 103 | C.CustomerID = O.CustomerID 104 | WHERE O.OrderDate <= @orderDate 105 | ORDER BY 'Customer Name'; 106 | 107 | -- MySQL: 108 | DELIMITER $$ 109 | CREATE PROCEDURE `spFilterProductsByNRP` (IN priceLevel FLOAT) 110 | 111 | BEGIN 112 | 113 | # to test: USE packt_online_shop; 114 | # CALL spFilterProductsByNRP(10.50); 115 | 116 | SELECT ProductName, WholesalePrice, NetRetailPrice, 117 | CASE 118 | WHEN NetRetailPrice <= 24.99 THEN 'Cheap' 119 | WHEN NetRetailPrice > 24.99 AND 120 | NetRetailPrice <= 79.99 THEN 'Mid-price' 121 | WHEN NetRetailPrice > 79.99 AND 122 | NetRetailPrice <= 2499.99 THEN 'Expensive' 123 | ELSE 'Very Expensive' 124 | END AS 'Price Point', 125 | UnitKGWeight 126 | FROM products 127 | WHERE NetRetailPrice <= priceLevel 128 | ORDER BY ProductName; 129 | 130 | END$$ 131 | 132 | 133 | /****** EXERCISE 2 ******/ 134 | 135 | CREATE PROCEDURE `spCustomerOrders` (IN orderDate datetime) 136 | 137 | # to test: USE packt_online_shop; 138 | # CALL spCustomerOrders('2010-01-02'); 139 | 140 | SELECT CONCAT(C.FirstName, ' ', C.LastName) as 'Customer Name', 141 | O.OrderNumber, O.OrderDate 142 | FROM orders O INNER JOIN customers C ON 143 | C.CustomerID = O.CustomerID 144 | WHERE O.OrderDate <= orderDate 145 | ORDER BY 'Customer Name'; 146 | 147 | 148 | USE packt_online_shop; 149 | 150 | DELIMITER $$ 151 | 152 | CREATE PROCEDURE `spFilterProductsByNRP` (IN priceLevel FLOAT) 153 | BEGIN 154 | 155 | # to test: USEpackt_online_shop; 156 | # CALL spFilterProductsByNRP(10.50); 157 | 158 | SELECT ProductName, WholesalePrice, NetRetailPrice, 159 | CASE 160 | WHEN NetRetailPrice <= 24.99 THEN 'Cheap' 161 | WHEN NetRetailPrice > 24.99 AND 162 | NetRetailPrice <= 79.99 THEN 'Mid-price' 163 | WHEN NetRetailPrice > 79.99 AND 164 | NetRetailPrice <= 2499.99 THEN 'Expensive' 165 | ELSE 'Very Expensive' 166 | END AS 'Price Point', 167 | UnitKGWeight 168 | FROM products 169 | WHERE products.NetRetailPrice <= priceLevel 170 | ORDER BY ProductName; 171 | 172 | END$$ 173 | 174 | DELIMITER ; 175 | 176 | 177 | /****** EXERCISE 3 ******/ 178 | 179 | -- SQL SERVER: 180 | 181 | ALTER PROCEDURE spFilterProductsByNRP 182 | 183 | @priceLevel float, 184 | @unitWeight float 185 | 186 | AS 187 | 188 | -- to test: spFilterProductsByNRP 206.00, 1.0 189 | 190 | SELECT ProductName, WholesalePrice, NetRetailPrice, 191 | CASE 192 | WHEN NetRetailPrice <= 24.99 THEN 'Cheap' 193 | WHEN NetRetailPrice > 24.99 AND 194 | NetRetailPrice <= 79.99 THEN 'Mid-price' 195 | WHEN NetRetailPrice > 79.99 AND 196 | NetRetailPrice <= 2499.99 THEN 'Expensive' 197 | ELSE 'Very Expensive' 198 | END AS 'Price Point', 199 | UnitKGWeight 200 | FROM products 201 | WHERE NetRetailPrice <= @priceLevel AND 202 | UnitKGWeight <= @unitWeight 203 | ORDER BY ProductName; 204 | 205 | -- MySQL: 206 | DELIMITER $$ 207 | CREATE DEFINER=`root`@`localhost` PROCEDURE `spFilterProductsByNRP`(IN priceLevel FLOAT, IN unitWeight FLOAT) 208 | 209 | BEGIN 210 | 211 | # to test: USE packt_online_shop; 212 | # CALL spFilterProductsByNRP(10.50, 1.0); 213 | 214 | SELECT ProductName, WholesalePrice, NetRetailPrice, 215 | CASE 216 | WHEN NetRetailPrice <= 24.99 THEN 'Cheap' 217 | WHEN NetRetailPrice > 24.99 AND 218 | NetRetailPrice <= 79.99 THEN 'Mid-price' 219 | WHEN NetRetailPrice > 79.99 AND 220 | NetRetailPrice <= 2499.99 THEN 'Expensive' 221 | ELSE 'Very Expensive' 222 | END AS 'Price Point', 223 | UnitKGWeight, 224 | AvailableQuantity # New column requested by PACKT #management for Products webpage 225 | FROM products 226 | WHERE NetRetailPrice <= priceLevel AND 227 | UnitKGWeight <= unitWeight # Filter with unitWeight parameter value 228 | ORDER BY ProductName; 229 | 230 | END$$ 231 | 232 | 233 | /****** ACTIVITY 1 SOLUTION ******/ 234 | 235 | -- SQL Server: 236 | 237 | CREATE PROCEDURE [dbo].[spFilterOrdersByItemQuantity] 238 | 239 | @orderItemQuantityVal int 240 | 241 | AS 242 | 243 | -- to test: spFilterOrdersByItemQuantity 25 244 | 245 | SELECT O.OrderID, SUM(OI.Quantity) AS 'Total Order Item Quantity' 246 | FROM Orders O INNER JOIN OrderItems OI ON 247 | O.OrderID = OI.OrderID 248 | GROUP BY O.OrderID 249 | HAVING SUM(OI.Quantity) <= @orderItemQuantityVal 250 | ORDER BY O.OrderID; 251 | 252 | GO 253 | 254 | 255 | -- MySQL: 256 | 257 | USE packt_online_shop; 258 | 259 | DELIMITER $$ 260 | 261 | CREATE PROCEDURE `spFilterOrdersByItemQuantity` (IN orderItemQuantityVal int) 262 | BEGIN 263 | 264 | # to test: USE packt_online_shop; 265 | 266 | # CALL spFilterOrdersByItemQuantity(25); 267 | 268 | SELECT O.OrderID, SUM(OI.Quantity) AS 'Total Order Item Quantity' 269 | FROM Orders O INNER JOIN 270 | OrderItems OI ON O.OrderID = OI.OrderID 271 | GROUP BY O.OrderID 272 | HAVING SUM(OI.Quantity) <= orderItemQuantityVal 273 | ORDER BY O.OrderID; 274 | 275 | END$$ 276 | 277 | DELIMITER ; 278 | 279 | 280 | /****** FUNCTIONS ******/ 281 | 282 | -- SQL SERVER: 283 | 284 | DECLARE @var1 INT, @var2 NVARCHAR(500) = 'A test string' -- 1. Declare variables and 285 | -- assign a value to a 286 | -- variable 287 | 288 | SET @var1 = 3 -- 2. Set @var1 to 3 289 | 290 | SELECT LOG(@var1) -- 3. The natural log function 291 | 292 | SELECT @var1 -- 4. @var1 did not change 293 | 294 | SELECT EXP(LOG(@var1)) -- 5. Nested function calls: natural log, then exponential 295 | 296 | SELECT LOG(EXP(@var1)) -- 6. Nested function calls: exponential, then natural log 297 | 298 | SELECT @var1 -- 7. @var1 did not change 299 | 300 | SET @var1 = @var1 * 5 -- 8. @var1 has a new value 301 | 302 | SELECT @var1 -- 9. Select @var1 303 | 304 | SELECT @var2 -- 10. Set @var2 = natural log of @var1 305 | 306 | SELECT UPPER(@var2) -- 11. Select UPPER CASE @var2 307 | 308 | 309 | -- MySQL: 310 | 311 | SET @var1 = NULL, @var2 = 'A test string'; # 1. Declare variables and 312 | # assign a value to a variable 313 | 314 | SET @var1 = 3; # 2. Set @var1 to 3 315 | 316 | SELECT LOG(@var1); # 3. Select the natural log of @var1 317 | 318 | SELECT @var1; # 4. @var1 did not change 319 | 320 | SELECT EXP(LOG(@var1)); # 5. Nested function calls: natural log, then exponential 321 | 322 | SELECT LOG(EXP(@var1)); # 6. Nested function calls: exponential, then natural log 323 | 324 | SELECT @var1; # 7. @var1 did not change 325 | 326 | SET @var1 = @var1 * 5; # 8. @var1 has a new value 327 | 328 | SELECT @var1; # 9. Select @var1 329 | 330 | SELECT @var2; # 10. Set @var2 = natural log of @var1 331 | 332 | SELECT UPPER(@var2); # 11. Select UPPER CASE @var2 333 | 334 | 335 | DECLARE @custID AS INT = 3; 336 | 337 | SELECT SUM((OI.Quantity * (OI.UnitPrice - OI.Discount))) 338 | FROM OrderItems OI INNER JOIN Orders O ON 339 | OI.OrderID = O.OrderID 340 | WHERE O.CustomerID = @custID; 341 | 342 | 343 | CREATE FUNCTION [dbo].[fnTotalSalesRvnByCust] (@CustomerID int) 344 | RETURNS float -- The return value data type 345 | AS 346 | 347 | BEGIN 348 | 349 | /* 350 | 351 | To test: 352 | 353 | SELECT dbo.fnTotalSalesRvnByCust(12) 354 | SELECT dbo.fnTotalSalesRvnByCust(3) 355 | 356 | */ 357 | 358 | DECLARE @retVal float; -- Variable to hold the return value 359 | 360 | SELECT @retVal = SUM(OI.Quantity * (OI.UnitPrice - OI.Discount)) 361 | FROM OrderItems OI INNER JOIN Orders O ON 362 | OI.OrderID = O.OrderID 363 | WHERE O.CustomerID = @CustomerID 364 | 365 | IF (@retVal IS NULL) -- If a customer has not placed an order, (s)he 366 | -- has a total revenue value of null. We'll have 367 | -- an easier time dealing with a 0.00 return 368 | -- value in that case. 369 | 370 | BEGIN 371 | SET @retVal = 0.00; 372 | END 373 | 374 | RETURN @retVal; 375 | 376 | END; 377 | 378 | 379 | SELECT CONCAT(FirstName, ' ', LastName) AS 'Customer Name', 380 | CustomerID, dbo.fnTotalSalesRvnByCust(CustomerID) AS 'Total Customer Revenue' 381 | FROM Customers 382 | 383 | 384 | 385 | 386 | 387 | /****** EXERCISE 4 ******/ 388 | 389 | -- SQL SERVER: 390 | 391 | CREATE FUNCTION dbo.fnCountCustomerOrders (@CustomerID int) 392 | 393 | RETURNS INT 394 | 395 | AS 396 | 397 | BEGIN 398 | 399 | /* 400 | 401 | To test: 402 | 403 | SELECT dbo.fnCountCustomerOrders(12) 404 | SELECT dbo.fnCountCustomerOrders(3) 405 | 406 | */ 407 | 408 | DECLARE @retVal int; 409 | 410 | SELECT @retVal = COUNT(O.OrderID) 411 | FROM Orders O INNER JOIN Customers C ON 412 | O.CustomerID = C.CustomerID 413 | WHERE C.CustomerID = @CustomerID 414 | 415 | RETURN @retVal; 416 | 417 | END; 418 | 419 | 420 | -- MySQL: 421 | DELIMITER $$ 422 | CREATE FUNCTION `fnTotalSalesRvnByCust` (CustomerID Integer) 423 | RETURNS FLOAT 424 | DETERMINISTIC 425 | BEGIN 426 | 427 | /* 428 | 429 | To test: 430 | 431 | SELECT packt_online_shop.fnTotalSalesRvnByCust (12); 432 | SELECT packt_online_shop.fnTotalSalesRvnByCust (3); 433 | 434 | */ 435 | 436 | DECLARE retVal FLOAT; 437 | 438 | SET retVal = ( 439 | SELECT SUM(OI.Quantity * (OI.UnitPrice - OI.Discount)) 440 | FROM OrderItems OI INNER JOIN Orders O ON 441 | OI.OrderID = O.OrderID 442 | WHERE O.CustomerID = CustomerID 443 | ); 444 | 445 | IF (retVal IS NULL) THEN -- If a customer has not placed an order, (s)he 446 | -- has a total revenue value of null. We'll 447 | -- have an easier time dealing with a 0.00 448 | -- return value in that case. 449 | 450 | SET retVal = 0.00; 451 | END IF; 452 | 453 | RETURN (retVal); 454 | END$$ 455 | 456 | 457 | SELECT packt_online_shop.fnTotalSalesRvnByCust (12); 458 | SELECT packt_online_shop.fnTotalSalesRvnByCust (3); 459 | 460 | 461 | /****** EXERCISE 5 ******/ 462 | 463 | -- MySQL: 464 | DELIMITER $$ 465 | CREATE FUNCTION `fnCountCustomerOrders` (CustomerID Integer) 466 | RETURNS INTEGER 467 | DETERMINISTIC 468 | BEGIN 469 | 470 | /* 471 | To test: 472 | 473 | SELECT packt_online_shop.fnCountCustomerOrders (12); 474 | SELECT packt_online_shop.fnCountCustomerOrders (3); 475 | 476 | */ 477 | 478 | DECLARE retVal INTEGER; 479 | 480 | SET retVal = ( 481 | SELECT COUNT(O.OrderID) 482 | FROM Orders O INNER JOIN Customers C ON 483 | O.CustomerID = C.CustomerID 484 | WHERE C.CustomerID = CustomerID 485 | ); 486 | 487 | RETURN(retVal); 488 | END$$ 489 | 490 | 491 | /****** ACTIVITY 2 SOLUTION ******/ 492 | 493 | -- SQL SERVER: 494 | 495 | CREATE FUNCTION dbo.fnProductTotalOrderQty (@ProductID int) 496 | RETURNS INT 497 | AS 498 | 499 | BEGIN 500 | 501 | /* 502 | To test: 503 | 504 | SELECT dbo.fnProductTotalOrderQty(12) 505 | SELECT dbo.fnProductTotalOrderQty(3) 506 | */ 507 | 508 | DECLARE @retVal AS INT; 509 | 510 | SET @retVal = ( 511 | SELECT 512 | CASE 513 | WHEN SUM(OI.quantity) IS NULL THEN 0 514 | ELSE 515 | SUM(OI.quantity) 516 | END AS 'quantity' 517 | 518 | FROM OrderItems OI 519 | WHERE OI.Productid = @ProductID 520 | ); 521 | 522 | RETURN @retVal; 523 | 524 | END; 525 | 526 | GO 527 | 528 | -- MySQL: 529 | DELIMITER $$ 530 | CREATE DEFINER =`root`@`localhost` FUNCTION `fnProductTotalOrderQty`(ProductID INT) 531 | RETURNS INT 532 | DETERMINISTIC 533 | BEGIN 534 | 535 | /* 536 | 537 | To test: 538 | 539 | SELECT packt_online_shop.fnProductTotalOrderQty(12); 540 | SELECT packt_online_shop.fnProductTotalOrderQty(3); 541 | */ 542 | 543 | 544 | 545 | DECLARE retVal INT; 546 | 547 | SET retVal = ( 548 | SELECT 549 | CASE 550 | WHEN SUM(OI.quantity) IS NULL THEN 0 551 | ELSE 552 | SUM(OI.quantity) 553 | END AS 'quantity' 554 | FROM OrderItems OI 555 | WHERE OI.Productid = ProductID 556 | ); 557 | RETURN retVal; 558 | END$$ 559 | 560 | 561 | /****** TRIGGERS ******/ 562 | 563 | -- SQL Server: 564 | 565 | CREATE TRIGGER tr_Basic 566 | ON Payments 567 | AFTER INSERT 568 | AS 569 | 570 | BEGIN 571 | 572 | /* 573 | To test: INSERT INTO Payments(OrderID, PaymentDate, PaymentType, 574 | PaymentRef, Amount, Notes, BalanceNotes) 575 | 576 | VALUES (1, '20140303', 'credit card', 'W26UA4', 577 | $7.10, 'payment received', NULL) 578 | */ 579 | 580 | SELECT 'Basic trigger for the Payments table' 581 | 582 | END 583 | 584 | 585 | CREATE TRIGGER tr_OrderItems_OnInsert 586 | ON OrderItems 587 | AFTER INSERT 588 | AS 589 | BEGIN 590 | 591 | /* 592 | To test: INSERT INTO OrderItems(OrderID, ProductID, Quantity, 593 | UnitPrice, Discount, Notes) 594 | VALUES(1, 6, 12, 4.49, 0.00, NULL) 595 | 596 | SELECT C.BalanceNotes 597 | FROM Customers C 598 | WHERE C.CustomerID = 2 599 | 600 | */ 601 | 602 | DECLARE @customerID INT, @orderBalance MONEY, @paymentBalance MONEY, 603 | @runningTotal MONEY 604 | 605 | DECLARE @OrderID INT, @balanceNotesText NVARCHAR(1000) 606 | 607 | -- The "INSERTED" table has the CustomerID and OrderID values we'll need 608 | 609 | SELECT @orderID = OrderID FROM INSERTED 610 | 611 | -- Find the customerID for that order 612 | 613 | SELECT @customerID = O.CustomerID 614 | FROM Orders O 615 | WHERE OrderID = @OrderID 616 | 617 | -- Calculate the order balance for the customer 618 | 619 | SELECT @orderBalance = SUM(OI.Quantity * (OI.UnitPrice - OI.Discount)) 620 | FROM OrderItems OI INNER JOIN Orders O ON 621 | OI.OrderID = O.OrderID 622 | WHERE O.CustomerID = @CustomerID 623 | 624 | -- Calculate the payment balance for the customer 625 | 626 | SELECT @paymentBalance = SUM(P.Amount) 627 | FROM Payments P INNER JOIN Orders O ON 628 | P.OrderID = O.OrderID 629 | WHERE O.CustomerID = @CustomerID 630 | 631 | -- Calculate the running total, and convert the value to NVARCHAR 632 | 633 | SET @runningTotal = CAST((@orderBalance - @paymentBalance) AS NVARCHAR) 634 | 635 | -- Build the @balanceNotesText string 636 | 637 | SET @balanceNotesText = CONCAT('Customer ', CAST(@customerID AS NVARCHAR)) 638 | SET @balanceNotesText = CONCAT(@balanceNotesText, ' has a new running balance of $') 639 | 640 | /* 641 | 642 | The GETDATE() function has the datestamp value we need; 643 | use the CONVERT function to format the datestamp value 644 | */ 645 | 646 | SET @balanceNotesText += CONCAT(@runningTotal, ' as of ') 647 | SET @balanceNotesText += CONVERT(VARCHAR, GETDATE(), 107) 648 | 649 | -- Update the Customers.BalanceNotes column for that specific @customerID 650 | 651 | UPDATE Customers 652 | SET Customers.BalanceNotes = @balanceNotesText 653 | WHERE CustomerID = @customerID 654 | 655 | END 656 | 657 | 658 | INSERT INTO OrderItems(OrderID, ProductID, Quantity, 659 | UnitPrice, Discount, Notes) 660 | VALUES(1, 6, 12, 4.49, 0.00, NULL) 661 | 662 | SELECT C.BalanceNotes 663 | FROM Customers C 664 | WHERE C.CustomerID = 2 665 | 666 | 667 | CREATE TRIGGER tr_Payments_OnInsert 668 | ON Payments 669 | AFTER INSERT 670 | AS 671 | BEGIN 672 | 673 | /* 674 | To test: INSERT INTO Payments(OrderID, PaymentDate, PaymentType, 675 | PaymentRef, Amount, Notes, BalanceNotes) 676 | VALUES(1, GETDATE(), 'check', 'SDGH4A', 12.97, NULL, NULL) 677 | 678 | SELECT C.BalanceNotes 679 | FROM Customers C 680 | WHERE C.CustomerID = 2 681 | 682 | */ 683 | 684 | DECLARE @customerID INT, @orderBalance MONEY, @paymentBalance MONEY 685 | DECLARE @runningTotal MONEY, @OrderID INT, @balanceNotesText NVARCHAR(1000) 686 | 687 | -- The "INSERTED" table has the CustomerID and OrderID values we'll need 688 | 689 | SELECT @orderID = OrderID FROM INSERTED 690 | 691 | -- Find the customerID for that order 692 | 693 | SELECT @customerID = O.CustomerID 694 | FROM Orders O 695 | WHERE OrderID = @OrderID 696 | 697 | -- Calculate the order balance for the customer 698 | 699 | SELECT @orderBalance = SUM(OI.Quantity * (OI.UnitPrice - OI.Discount)) 700 | FROM OrderItems OI INNER JOIN Orders O ON 701 | OI.OrderID = O.OrderID 702 | WHERE O.OrderID = @OrderID 703 | 704 | -- Calculate the payment balance for the customer 705 | 706 | SELECT @paymentBalance = SUM(P.Amount) 707 | FROM Payments P INNER JOIN Orders O ON 708 | P.OrderID = O.OrderID 709 | WHERE O.CustomerID = @CustomerID 710 | 711 | -- Calculate the running total, and convert the value to NVARCHAR 712 | 713 | SET @runningTotal = CAST((@orderBalance - @paymentBalance) AS NVARCHAR) 714 | 715 | -- Build the @balanceNotesText string 716 | 717 | SET @balanceNotesText = CONCAT('Customer ', CAST(@customerID AS NVARCHAR)) 718 | SET @balanceNotesText = CONCAT(@balanceNotesText, ' has a new running balance of $') 719 | SET @balanceNotesText += CONCAT(@runningTotal, ' as of ') 720 | 721 | /* 722 | 723 | The GETDATE() function has the datestamp value we need; 724 | use the CONVERT function to format the datestamp value 725 | */ 726 | 727 | SET @balanceNotesText += CONVERT(VARCHAR, GETDATE(), 107) 728 | 729 | -- Update the Customers.BalanceNotes column for that specific @customerID 730 | 731 | UPDATE Customers 732 | SET Customers.BalanceNotes = @balanceNotesText 733 | WHERE CustomerID = @customerID 734 | 735 | END 736 | 737 | 738 | INSERT INTO Payments(OrderID, PaymentDate, PaymentType, 739 | PaymentRef, Amount, Notes, BalanceNotes) 740 | VALUES(1, GETDATE(), 'check', 'SDGH4A', 12.97, NULL, NULL) 741 | 742 | SELECT C.BalanceNotes 743 | FROM Customers C 744 | WHERE C.CustomerID = 2 745 | 746 | 747 | /****** EXERCISE 6 ******/ 748 | 749 | -- SQL SERVER: 750 | 751 | CREATE TRIGGER tr_Products_OnInsert 752 | ON Products 753 | AFTER INSERT 754 | AS 755 | BEGIN 756 | 757 | /* 758 | To test: INSERT INTO Products(ProductCategoryID, SupplierID, ProductName, ProductImage, NetRetailPrice, 759 | AvailableQuantity, WholesalePrice, UnitKGWeight, Notes) 760 | VALUES(3, 4,'peanut butter', NULL, 3.79, 1000, 2.69, 0.75, 'caution: high calorie') 761 | 762 | SELECT S.* 763 | FROM Suppliers S 764 | WHERE S.SupplierID = 4 765 | */ 766 | 767 | DECLARE @supplierID INT, @supplierProductCount INT 768 | DECLARE @supplierCountText NVARCHAR(1000) 769 | 770 | -- The "INSERTED" table has the CustomerID and OrderID 771 | -- values we'll need 772 | 773 | SELECT @supplierID = supplierID FROM INSERTED 774 | 775 | -- Calculate the supplier product count, and convert 776 | -- the value to NVARCHAR 777 | 778 | SELECT @supplierProductCount = COUNT(P.ProductID) 779 | FROM Products P INNER JOIN Suppliers S ON 780 | P.SupplierID = S.SupplierID 781 | WHERE S.SupplierID = @supplierID 782 | 783 | SET @supplierCountText = CONCAT('This supplier (Supplier ', CAST(@supplierID AS NVARCHAR), ')') 784 | SET @supplierCountText += CONCAT(' has ', CAST(@supplierProductCount AS NVARCHAR)) 785 | SET @supplierCountText += ' products available here at Packt as of ' 786 | SET @supplierCountText += CONVERT(VARCHAR, GETDATE(), 107) 787 | 788 | -- Update the Customers.BalanceNotes column for 789 | -- that specific @customerID 790 | 791 | UPDATE Suppliers 792 | SET Suppliers.Notes = @supplierCountText 793 | WHERE SupplierID = @supplierID 794 | 795 | END 796 | 797 | 798 | -- MySQL: 799 | 800 | USE packt_online_shop; 801 | 802 | # drop trigger tr_Basic; 803 | 804 | /* 805 | 806 | To test: USE packt_online_shop; 807 | 808 | INSERT INTO Payments(OrderID, PaymentDate, PaymentType, PaymentRef, Amount, Notes, BalanceNotes) 809 | VALUES (1, '20140303', 'credit card', 'W26UA4', 7.10, 'payment received', NULL); 810 | 811 | SELECT * FROM CUSTOMERS; 812 | 813 | */ 814 | 815 | DELIMITER $$ 816 | 817 | CREATE TRIGGER tr_Basic AFTER INSERT ON Payments 818 | FOR EACH ROW 819 | BEGIN 820 | 821 | DECLARE customerID INT; 822 | SET customerID = ( 823 | SELECT O.CustomerID 824 | FROM Orders O 825 | WHERE O.OrderID = NEW.OrderID 826 | ); 827 | 828 | UPDATE Customers 829 | 830 | SET Customers.BalanceNotes = CONCAT('Customer ', CAST(customerID AS CHAR), ' just got updated again') 831 | WHERE Customers.CustomerID = customerID; 832 | 833 | END$$ 834 | 835 | DELIMITER ; 836 | 837 | 838 | USE packt_online_shop; 839 | 840 | # drop trigger tr_OrderItems_OnInsert 841 | 842 | DELIMITER $$ 843 | 844 | # Basic syntax to create the tr_OrderItems_OnInsert trigger 845 | # to fire after every OrderItems table row insertion. 846 | 847 | CREATE TRIGGER tr_OrderItems_OnInsert AFTER INSERT ON OrderItems 848 | FOR EACH ROW 849 | BEGIN 850 | 851 | /* 852 | 853 | To test: INSERT INTO OrderItems(OrderID, ProductID, Quantity, 854 | UnitPrice, Discount, Notes) 855 | VALUES(1, 6, 12, 4.49, 0.00, NULL); 856 | 857 | SELECT C.BalanceNotes 858 | FROM Customers C 859 | WHERE C.CustomerID = 2; 860 | */ 861 | 862 | # Assign the needed variable values, in order. 863 | # SELECT the values and assign then to the 864 | # variables with the SET command. For this, 865 | # place all SELECT statements in parentheses. 866 | 867 | DECLARE balanceNotesText VARCHAR(1000); 868 | DECLARE customerID INT; 869 | DECLARE orderBalance DECIMAL(10, 2); 870 | DECLARE orderIDVal INT; 871 | DECLARE paymentBalance DECIMAL(10, 2); 872 | DECLARE runningTotal DECIMAL(10, 2); 873 | 874 | # The "NEW" table has the CustomerID and OrderID values 875 | # from the new inserted row that we'll need. 876 | 877 | SET orderIDVal = ( 878 | SELECT NEW.orderID 879 | ); 880 | 881 | SET customerID = ( 882 | SELECT O.CustomerID 883 | FROM Orders O 884 | WHERE OrderID = orderIDVal 885 | ); 886 | 887 | # Calculate the order balance for the customer 888 | 889 | SET orderBalance = ( 890 | SELECT SUM(OI.Quantity * (OI.UnitPrice - OI.Discount)) 891 | FROM OrderItems OI INNER JOIN Orders O ON 892 | OI.OrderID = O.OrderID 893 | WHERE O.CustomerID = CustomerID 894 | ); 895 | 896 | # Calculate the payment balance for the customer 897 | 898 | SET paymentBalance = ( 899 | SELECT SUM(P.Amount) 900 | FROM Payments P INNER JOIN Orders O ON 901 | P.OrderID = O.OrderID 902 | WHERE O.CustomerID = CustomerID 903 | ); 904 | 905 | # Calculate the running total, and convert the value to CHAR 906 | 907 | SET runningTotal = ( 908 | SELECT CAST((orderBalance - paymentBalance) AS CHAR) 909 | ); 910 | 911 | # Build the balanceNotesText string 912 | 913 | SET balanceNotesText = ( 914 | SELECT CONCAT("Customer ", CAST(customerID AS CHAR)) 915 | ); 916 | 917 | SET balanceNotesText = ( 918 | SELECT CONCAT(balanceNotesText, " has a new running balance of $") 919 | ); 920 | 921 | # 922 | # The NOW() function has the datestamp value we need; 923 | # use the CONVERT function to format the datestamp value 924 | # 925 | 926 | SET balanceNotesText = ( 927 | SELECT CONCAT(balanceNotesText, runningTotal, ' as of ') 928 | 929 | ); 930 | 931 | SET balanceNotesText = ( 932 | SELECT CONCAT(balanceNotesText, DATE_FORMAT(NOW(), "%b %d, %Y")) 933 | ); 934 | 935 | # Update the Customers.BalanceNotes column for that specific customerID 936 | 937 | UPDATE Customers 938 | SET Customers.BalanceNotes = balanceNotesText 939 | WHERE Customers.CustomerID = customerID; 940 | 941 | END$$ 942 | 943 | DELIMITER ; 944 | 945 | 946 | USE packt_online_shop; 947 | 948 | # drop trigger tr_Payments_OnInsert 949 | 950 | DELIMITER $$ 951 | 952 | # Basic syntax to create the tr_Payments_OnInsert trigger 953 | # to fire after every payments table row insertion. 954 | 955 | CREATE TRIGGER tr_Payments_OnInsert AFTER INSERT ON payments 956 | FOR EACH ROW 957 | BEGIN 958 | 959 | /* 960 | 961 | To test: INSERT INTO Payments(OrderID, PaymentDate, PaymentType, 962 | PaymentRef, Amount, Notes, BalanceNotes) 963 | VALUES(1, NOW(), 'check', 'SDGH4A', 12.97, NULL, NULL); 964 | 965 | SELECT C.BalanceNotes 966 | FROM Customers C 967 | WHERE C.CustomerID = 2; 968 | */ 969 | 970 | # Assign the needed variable values, in order. 971 | # SELECT the values and assign then to the 972 | # variables with the SET command. For this, 973 | # place all SELECT statements in parentheses. 974 | 975 | DECLARE balanceNotesText VARCHAR(1000); 976 | DECLARE customerID INT; 977 | DECLARE orderBalance DECIMAL(10, 2); 978 | DECLARE orderIDVal INT; 979 | DECLARE paymentBalance DECIMAL(10, 2); 980 | DECLARE runningTotal DECIMAL(10, 2); 981 | 982 | # The "NEW" table has the CustomerID and OrderID values 983 | # from the new inserted row that we'll need. 984 | 985 | SET orderIDVal = ( 986 | SELECT NEW.orderID 987 | ); 988 | 989 | SET customerID = ( 990 | SELECT O.CustomerID 991 | FROM Orders O 992 | WHERE OrderID = orderIDVal 993 | ); 994 | 995 | # Calculate the order balance for the customer 996 | 997 | SET orderBalance = ( 998 | SELECT SUM(OI.Quantity * (OI.UnitPrice - OI.Discount)) 999 | FROM OrderItems OI INNER JOIN Orders O ON 1000 | OI.OrderID = O.OrderID 1001 | WHERE O.CustomerID = CustomerID 1002 | ); 1003 | 1004 | # Calculate the payment balance for the customer 1005 | 1006 | SET paymentBalance = ( 1007 | SELECT SUM(P.Amount) 1008 | FROM Payments P INNER JOIN Orders O ON 1009 | P.OrderID = O.OrderID 1010 | WHERE O.CustomerID = CustomerID 1011 | 1012 | ); 1013 | 1014 | # Calculate the running total, and convert the value to CHAR 1015 | 1016 | SET runningTotal = ( 1017 | SELECT CAST((orderBalance - paymentBalance) AS CHAR) 1018 | ); 1019 | 1020 | # Build the balanceNotesText string 1021 | 1022 | SET balanceNotesText = ( 1023 | SELECT CONCAT("Customer ", CAST(customerID AS CHAR)) 1024 | ); 1025 | 1026 | SET balanceNotesText = ( 1027 | SELECT CONCAT(balanceNotesText, " has a new running balance of $") 1028 | ); 1029 | 1030 | # 1031 | # The NOW() function has the datestamp value we need; 1032 | # use the CONVERT function to format the datestamp value 1033 | # 1034 | 1035 | SET balanceNotesText = ( 1036 | SELECT CONCAT(balanceNotesText, runningTotal, ' as of ') 1037 | ); 1038 | 1039 | SET balanceNotesText = ( 1040 | SELECT CONCAT(balanceNotesText, DATE_FORMAT(NOW(), "%b %d, %Y")) 1041 | ); 1042 | 1043 | # Update the Customers.BalanceNotes column for that specific customerID 1044 | 1045 | UPDATE Customers 1046 | SET Customers.BalanceNotes = balanceNotesText 1047 | WHERE Customers.CustomerID = customerID; 1048 | 1049 | END$$ 1050 | 1051 | DELIMITER ; 1052 | 1053 | 1054 | /****** EXERCISE 7 ******/ 1055 | 1056 | -- MySQL: 1057 | 1058 | USE packt_online_shop; 1059 | 1060 | # drop trigger tr_Products_OnInsert 1061 | 1062 | DELIMITER $$ 1063 | 1064 | # Basic syntax to create the tr_Products_OnInsert trigger 1065 | # to fire after every OrderItems table row insertion. 1066 | 1067 | CREATE TRIGGER tr_Products_OnInsert AFTER INSERT ON Products 1068 | FOR EACH ROW 1069 | BEGIN 1070 | 1071 | /* 1072 | 1073 | To test: INSERT INTO Products(ProductCategoryID, SupplierID, 1074 | ProductName, ProductImage, NetRetailPrice, 1075 | AvailableQuantity, WholesalePrice, 1076 | UnitKGWeight, Notes) 1077 | VALUES(3, 3, 'peanut butter', NULL, 3.79, 1000, 2.69, 1078 | 0.75, 'caution: high calorie'); 1079 | 1080 | SELECT P.* 1081 | FROM Products P 1082 | WHERE P.SupplierID = 3; 1083 | 1084 | */ 1085 | 1086 | DECLARE supplierID INT; 1087 | DECLARE supplierProductCount INT; 1088 | DECLARE supplierCountText VARCHAR(1000); 1089 | 1090 | # The "NEW" table has the SupplierID 1091 | # value we'll need 1092 | 1093 | SET supplierID = ( 1094 | SELECT NEW.supplierID 1095 | ); 1096 | 1097 | # Calculate the supplier product count, 1098 | # and convert the value to TEXT 1099 | 1100 | SET supplierProductCount = ( 1101 | SELECT COUNT(P.ProductID) 1102 | FROM Products P INNER JOIN Suppliers S ON 1103 | P.SupplierID = S.SupplierID 1104 | WHERE S.SupplierID = supplierID 1105 | ); 1106 | 1107 | SET supplierCountText = ( 1108 | SELECT CONCAT("This supplier (Supplier ", CAST(supplierID AS CHAR), ")") 1109 | ); 1110 | 1111 | SET supplierCountText = ( 1112 | SELECT CONCAT(supplierCountText, " has ", CAST(supplierProductCount AS CHAR)) 1113 | ); 1114 | 1115 | SET supplierCountText = ( 1116 | SELECT CONCAT(supplierCountText, " products available here at Packt as of ") 1117 | ); 1118 | 1119 | SET supplierCountText = ( 1120 | SELECT CONCAT(supplierCountText, DATE_FORMAT(NOW(), "%b %d, %Y")) 1121 | ); 1122 | 1123 | # Update the Customers.BalanceNotes column 1124 | # for that specific customerID 1125 | 1126 | UPDATE Suppliers 1127 | SET Suppliers.Notes = supplierCountText 1128 | WHERE Suppliers.SupplierID = supplierID; 1129 | 1130 | END$$ 1131 | 1132 | DELIMITER ; 1133 | --------------------------------------------------------------------------------