表結構與數據:https://github.com/XuePeng87/TSQLV4git
練習1
練習內容:編寫一個對Sales.Orders表的查詢,返回2015年6月的訂單 |
涉及的表:Sales.Orders |
輸出的列:orderid, orderdate, custid, empid |
正確結果:30行 |
SELECT orderid, orderdate, custid, empid
FROM Sales.Orders
WHERE orderdate BETWEEN '20150601' AND '20150630';
SELECT orderid, orderdate, custid, empid
FROM Sales.Orders
WHERE orderdate >= '20150601' AND orderdate < '20150701';
練習2
練習內容:編寫一個對Sales.Orders表的查詢,返回每個月最後一天的訂單 |
涉及的表:Sales.Orders |
輸出的列:orderid, orderdate, custid, empid |
正確結果:26行 |
SELECT orderid, orderdate, custid, empid
FROM Sales.Orders
WHERE orderdate = EOMONTH(orderdate);
上面的代碼中,函數EOMONTH是SQLServer2012加入的函數,若是在以前的版本則使用不了該函數,須要用到如下方式指定時期的月份的最後一天:github
SELECT orderid, orderdate, custid, empid
FROM Sales.Orders
WHERE orderdate = DATEADD(MONTH, DATEDIFF(month, '20151231', orderdate), '20151231');
先使用DATEFIDD函數計算固定的某月的最後一天與指定日期orderdate的月數差,在添加月數差到固定日期獲得指定日期orderdate月份的最後一天。sql
練習3
練習內容:編寫一個對HR.Employees表的查詢,返回姓氏包含字母"e"兩次及以上次數的僱員 |
涉及的表:HR.Employees |
輸出的列:empid, firstname, lastname |
正確結果:2行 |
SELECT empid, firstname, lastname
FROM HR.Employees
WHERE lastname LIKE '%e%e%';
練習4
練習內容:編寫一個對Sales.OrderDetails表的查詢,返回訂單總價(qty*unitprice)大於10000的訂單,按總價排序 |
涉及的表:Sales.OrderDetails |
輸出的列:orderid, totalvalue |
正確結果:14行 |
SELECT orderid, SUM(qty*unitprice) AS totalvalue
FROM Sales.OrderDetails
GROUP BY orderid
HAVING SUM(qty * unitprice) > 10000
ORDER BY totalvalue;
總價爲訂單總價,應該先對訂單進行分組,在經過聚合函數SUM計算訂單總價。函數
練習5
練習內容:編寫一個對Sales.Orders表的查詢,返回2015年中平均運費最高的3個國家 |
涉及的表:Sales.Orders |
輸出的列:shipcountry, avgfreight |
正確結果:3行 |
SELECT TOP 3 shipcountry, AVG(freight) AS avgfreight
FROM Sales.Orders
WHERE orderdate >= '20150101' AND orderdate < '20160101'
GROUP BY shipcountry
ORDER BY avgfreight DESC;
在SQLServer2012中,能夠使用OFFSET來提取前三名:spa
SELECT shipcountry, AVG(freight) AS avgfreight
FROM Sales.Orders
WHERE orderdate >= '20150101' AND orderdate < '20160101'
GROUP BY shipcountry
ORDER BY avgfreight DESC
OFFSET 0 ROWS FETCH FIRST 3 ROWS ONLY;
練習6
練習內容:編寫一個對Sales.Orders表的查詢,分別對每一個客戶的訂單按訂單日期排序(使用訂單ID做爲決勝屬性),爲每一個用戶的訂單添加排序編號。 |
涉及的表:Sales.Orders |
輸出的列:custid, orderdate, orderid, rownum |
正確結果:830行 |
SELECT custid, orderdate, orderid,
ROW_NUMBER() OVER(PARTITION BY custid ORDER BY orderdate, orderid) AS rownum
FROM Sales.Orders
ORDER BY custid, rownum;
練習7
練習內容:使用HR.Employees表,根據稱謂推測每一個僱員的性別。"Ms."和"Mrs."返回"Female","Mr."返回"Male",全部其餘狀況返回"Unknown" |
涉及的表:HR.Employees |
輸出的列:empid, firstname, lastname, titleofcourtesy, gender |
正確結果:9行 |
SELECT empid, firstname, lastname, titleofcourtesy,
CASE
WHEN titleofcourtesy ='Ms.' THEN 'Female'
WHEN titleofcourtesy = 'Mrs.' THEN 'Female'
WHEN titleofcourtesy = '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
練習內容:編寫一個對Sales.Customers表的查詢,返回客戶的ID和地區。按地區排序輸出行,具備NULL標記的行最後進行排序。 |
涉及的表:Sales.Customers |
輸出的列:custid, region |
正確結果:91行 |
SELECT custid, region
FROM Sales.Customers
ORDER BY
CASE WHEN region IS NULL THEN 1 ELSE 0 END, region;
SQLServer會把NULL放在前面,這裏須要處理這個問題,在ORDER BY子句中使用CASE,返回NULL返回1,不然返回0,先經過0和1排序,在經過region排序,這樣NULL就會被排到下面。code