Chapter 02 - Single-Table Queries - Solutions

 

---------------------------------------------------------------------
-- Microsoft SQL Server 2008 T-SQL Fundamentals
-- Chapter 2 - Single-Table Queries
-- Solutions
-- ?2008 Itzik Ben-Gan
---------------------------------------------------------------------

-- 1
-- Return orders placed on June 2007
-- Tables involved: TSQLFundamentals2008 database, Sales.Orders table

-- Desired output:
orderid     orderdate               custid      empid
----------- ----------------------- ----------- -----------
10555       2007-06-02 00:00:00.000 71          6
10556       2007-06-03 00:00:00.000 73          2
10557       2007-06-03 00:00:00.000 44          9
10558       2007-06-04 00:00:00.000 4           1
10559       2007-06-05 00:00:00.000 7           6
10560       2007-06-06 00:00:00.000 25          8
10561       2007-06-06 00:00:00.000 24          2
10562       2007-06-09 00:00:00.000 66          1
10563       2007-06-10 00:00:00.000 67          2
10564       2007-06-10 00:00:00.000 65          4
10565       2007-06-11 00:00:00.000 51          8
10566       2007-06-12 00:00:00.000 7           9
10567       2007-06-12 00:00:00.000 37          1
10568       2007-06-13 00:00:00.000 29          3
10569       2007-06-16 00:00:00.000 65          5
10570       2007-06-17 00:00:00.000 51          3
10571       2007-06-17 00:00:00.000 20          8
10572       2007-06-18 00:00:00.000 5           3
10573       2007-06-19 00:00:00.000 3           7
10574       2007-06-19 00:00:00.000 82          4
10575       2007-06-20 00:00:00.000 52          5
10576       2007-06-23 00:00:00.000 80          3
10577       2007-06-23 00:00:00.000 82          9
10578       2007-06-24 00:00:00.000 11          4
10579       2007-06-25 00:00:00.000 45          1
10580       2007-06-26 00:00:00.000 56          4
10581       2007-06-26 00:00:00.000 21          3
10582       2007-06-27 00:00:00.000 6           3
10583       2007-06-30 00:00:00.000 87          2
10584       2007-06-30 00:00:00.000 7           4

(30 row(s) affected)

-- Solution
USE TSQLFundamentals2008;

SELECT orderid, orderdate, custid, empid
FROM Sales.Orders
WHERE orderdate >= '20070601'
  AND orderdate < '20070701';

-- 2 (Optional, Advanced)
-- Return orders placed on the last day of the month
-- Tables involved: Sales.Orders table

-- Desired output:
orderid     orderdate               custid      empid
----------- ----------------------- ----------- -----------
10269       2006-07-31 00:00:00.000 89          5
10317       2006-09-30 00:00:00.000 48          6
10343       2006-10-31 00:00:00.000 44          4
10399       2006-12-31 00:00:00.000 83          8
10432       2007-01-31 00:00:00.000 75          3
10460       2007-02-28 00:00:00.000 24          8
10461       2007-02-28 00:00:00.000 46          1
10490       2007-03-31 00:00:00.000 35          7
10491       2007-03-31 00:00:00.000 28          8
10522       2007-04-30 00:00:00.000 44          4
10583       2007-06-30 00:00:00.000 87          2
10584       2007-06-30 00:00:00.000 7           4
10616       2007-07-31 00:00:00.000 32          1
10617       2007-07-31 00:00:00.000 32          4
10686       2007-09-30 00:00:00.000 59          2
10687       2007-09-30 00:00:00.000 37          9
10725       2007-10-31 00:00:00.000 21          4
10806       2007-12-31 00:00:00.000 84          3
10807       2007-12-31 00:00:00.000 27          4
10987       2008-03-31 00:00:00.000 19          8
10988       2008-03-31 00:00:00.000 65          3
10989       2008-03-31 00:00:00.000 61          2
11060       2008-04-30 00:00:00.000 27          2
11061       2008-04-30 00:00:00.000 32          4
11062       2008-04-30 00:00:00.000 66          4
11063       2008-04-30 00:00:00.000 37          3

(26 row(s) affected)

-- Solution
SELECT orderid, orderdate, custid, empid
FROM Sales.Orders
WHERE orderdate = DATEADD(month, DATEDIFF(month, '19991231', orderdate), '19991231');

-- 3
-- Return employees with last name containing the letter 'a' twice or more
-- Tables involved: HR.Employees table

-- Desired output:
empid       firstname  lastname
----------- ---------- --------------------
9           Zoya       Dolgopyatova

(1 row(s) affected)

-- Solution
SELECT empid, firstname, lastname
FROM HR.Employees
WHERE lastname LIKE '%a%a%';

-- 4
-- Return orders with total value(qty*unitprice) greater than 10000
-- sorted by total value
-- Tables involved: Sales.OrderDetails table

-- Desired output:
orderid     totalvalue
----------- ---------------------
10865       17250.00
11030       16321.90
10981       15810.00
10372       12281.20
10424       11493.20
10817       11490.70
10889       11380.00
10417       11283.20
10897       10835.24
10353       10741.60
10515       10588.50
10479       10495.60
10540       10191.70
10691       10164.80

(14 row(s) affected)

-- Solution
SELECT orderid, SUM(qty*unitprice) AS totalvalue
FROM Sales.OrderDetails
GROUP BY orderid
HAVING SUM(qty*unitprice) > 10000
ORDER BY totalvalue DESC;

-- 5
-- Return the three ship countries with the highest average freight in 2007
-- Tables involved: Sales.Orders table

-- Desired output:
shipcountry     avgfreight
--------------- ---------------------
Austria         178.3642
Switzerland     117.1775
Sweden          105.16

(3 row(s) affected)

-- Solution
SELECT TOP(3) shipcountry, AVG(freight) AS avgfreight
FROM Sales.Orders
WHERE orderdate >= '20070101' AND orderdate < '20080101'
GROUP BY shipcountry
ORDER BY avgfreight DESC;

-- 6
-- Calculate row numbers for orders
-- based on order date ordering (using order id as tiebreaker)
-- for each customer separately
-- Tables involved: Sales.Orders table

-- Desired output:
custid      orderdate               orderid     rownum
----------- ----------------------- ----------- --------------------
1           2007-08-25 00:00:00.000 10643       1
1           2007-10-03 00:00:00.000 10692       2
1           2007-10-13 00:00:00.000 10702       3
1           2008-01-15 00:00:00.000 10835       4
1           2008-03-16 00:00:00.000 10952       5
1           2008-04-09 00:00:00.000 11011       6
2           2006-09-18 00:00:00.000 10308       1
2           2007-08-08 00:00:00.000 10625       2
2           2007-11-28 00:00:00.000 10759       3
2           2008-03-04 00:00:00.000 10926       4
...

(830 row(s) affected)

-- Solution
SELECT custid, orderdate, orderid,
  ROW_NUMBER() OVER(PARTITION BY custid ORDER BY orderdate, orderid) AS rownum
FROM Sales.Orders
ORDER BY custid, rownum;

-- 7
-- Figure out and return for each employee the gender based on the title of courtesy
-- Ms., Mrs. - Female, Mr. - Male, Dr. - Unknown
-- Tables involved: HR.Employees table

-- Desired output:
empid       firstname  lastname             titleofcourtesy           gender
----------- ---------- -------------------- ------------------------- -------
1           Sara       Davis                Ms.                       Female
2           Don        Funk                 Dr.                       Unknown
3           Judy       Lew                  Ms.                       Female
4           Yael       Peled                Mrs.                      Female
5           Sven       Buck                 Mr.                       Male  
6           Paul       Suurs                Mr.                       Male  
7           Russell    King                 Mr.                       Male  
8           Maria      Cameron              Ms.                       Female
9           Zoya       Dolgopyatova         Ms.                       Female

(9 row(s) affected)

-- Solutions
SELECT empid, firstname, lastname, titleofcourtesy,
  CASE titleofcourtesy
    WHEN 'Ms.'  THEN 'Female'
    WHEN 'Mrs.' THEN 'Female'
    WHEN 'Mr.'  THEN 'Male'
    ELSE             'Unknown'
  END AS gender
FROM HR.Employees;

SELECT empid, firstname, lastname, titleofcourtesy,
  CASE
    WHEN titleofcourtesy IN('Ms.', 'Mrs.') THEN 'Female'
    WHEN titleofcourtesy = 'Mr.'           THEN 'Male'
    ELSE                                        'Unknown'
  END AS gender
FROM HR.Employees;

-- 8
-- Return for each customer the customer ID and region
-- sort the rows in the output by region
-- having NULLs sort last (after non-NULL values)
-- Note that the default in T-SQL is that NULL sort first
-- Tables involved: Sales.Customers table

-- Desired output:
custid      region
----------- ---------------
55          AK
10          BC
42          BC
45          CA
37          Co. Cork
33          DF
71          ID
38          Isle of Wight
46          Lara
78          MT
...
1           NULL
2           NULL
3           NULL
4           NULL
5           NULL
6           NULL
7           NULL
8           NULL
9           NULL
11          NULL
...

(91 row(s) affected)

-- Solution
SELECT custid, region
FROM Sales.Customers
ORDER BY
  CASE WHEN region IS NULL THEN 1 ELSE 0 END, region;

發佈了1 篇原創文章 · 獲贊 5 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章