Chapter 04 - Subqueries
来源:互联网 发布:淘宝店营销策划书范文 编辑:程序博客网 时间:2024/04/28 10:12
---------------------------------------------------------------------
-- Microsoft SQL Server 2008 T-SQL Fundamentals
-- Chapter 4 - Subqueries
-- ?2008 Itzik Ben-Gan
---------------------------------------------------------------------
---------------------------------------------------------------------
-- Self-Contained Subqueries
---------------------------------------------------------------------
---------------------------------------------------------------------
-- Scalar Subqueries
---------------------------------------------------------------------
-- Order with the maximum order ID
USE TSQLFundamentals2008;
DECLARE @maxid AS INT = (SELECT MAX(orderid)
FROM Sales.Orders);
SELECT orderid, orderdate, empid, custid
FROM Sales.Orders
WHERE orderid = @maxid;
GO
SELECT orderid, orderdate, empid, custid
FROM Sales.Orders
WHERE orderid = (SELECT MAX(O.orderid)
FROM Sales.Orders AS O);
-- Scalar subquery expected to return one value
SELECT orderid
FROM Sales.Orders
WHERE empid =
(SELECT E.empid
FROM HR.Employees AS E
WHERE E.lastname LIKE N'B%');
GO
SELECT orderid
FROM Sales.Orders
WHERE empid =
(SELECT E.empid
FROM HR.Employees AS E
WHERE E.lastname LIKE N'D%');
GO
SELECT orderid
FROM Sales.Orders
WHERE empid =
(SELECT E.empid
FROM HR.Employees AS E
WHERE E.lastname LIKE N'A%');
---------------------------------------------------------------------
-- Multi-Valued Subqueries
---------------------------------------------------------------------
SELECT orderid
FROM Sales.Orders
WHERE empid IN
(SELECT E.empid
FROM HR.Employees AS E
WHERE E.lastname LIKE N'D%');
SELECT O.orderid
FROM HR.Employees AS E
JOIN Sales.Orders AS O
ON E.empid = O.empid
WHERE E.lastname LIKE N'D%';
-- Orders placed by US customers
SELECT custid, orderid, orderdate, empid
FROM Sales.Orders
WHERE custid IN
(SELECT C.custid
FROM Sales.Customers AS C
WHERE C.country = N'USA');
-- Customers who placed no orders
SELECT custid, companyname
FROM Sales.Customers
WHERE custid NOT IN
(SELECT O.custid
FROM Sales.Orders AS O);
GO
-- Missing order IDs
USE tempdb;
IF OBJECT_ID('dbo.Orders') IS NOT NULL DROP TABLE dbo.Orders;
GO
SELECT *
INTO dbo.Orders
FROM TSQLFundamentals2008.Sales.Orders
WHERE orderid % 2 = 0;
SELECT n
FROM dbo.Nums
WHERE n BETWEEN (SELECT MIN(O.orderid) FROM dbo.Orders AS O)
AND (SELECT MAX(O.orderid) FROM dbo.Orders AS O)
AND n NOT IN (SELECT O.orderid FROM dbo.Orders AS O);
-- CLeanup
DROP TABLE tempdb.dbo.Orders;
---------------------------------------------------------------------
-- Correlated Subqueries
---------------------------------------------------------------------
-- Orders with maximum order ID for each customer
USE TSQLFundamentals2008;
SELECT custid, orderid, orderdate, empid
FROM Sales.Orders AS O1
WHERE orderid =
(SELECT MAX(O2.orderid)
FROM Sales.Orders AS O2
WHERE O2.custid = O1.custid);
SELECT MAX(O2.orderid)
FROM Sales.Orders AS O2
WHERE O2.custid = 85;
-- Percentage of store total
SELECT orderid, custid, val,
CAST(100. * val / (SELECT SUM(O2.val)
FROM Sales.OrderValues AS O2
WHERE O2.custid = O1.custid)
AS NUMERIC(5,2)) AS pct
FROM Sales.OrderValues AS O1
ORDER BY custid, orderid;
---------------------------------------------------------------------
-- EXISTS
---------------------------------------------------------------------
-- Customers from Spain who placed orders
SELECT custid, companyname
FROM Sales.Customers AS C
WHERE country = N'Spain'
AND EXISTS
(SELECT * FROM Sales.Orders AS O
WHERE O.custid = C.custid);
-- Customers from Spain who didn't place Orders
SELECT custid, companyname
FROM Sales.Customers AS C
WHERE country = N'Spain'
AND NOT EXISTS
(SELECT * FROM Sales.Orders AS O
WHERE O.custid = C.custid);
---------------------------------------------------------------------
-- Beyond the Fundamentals of Subqueries
-- (Optional, Advanced)
---------------------------------------------------------------------
---------------------------------------------------------------------
-- Returning "Previous" or "Next" Value
---------------------------------------------------------------------
SELECT orderid, orderdate, empid, custid,
(SELECT MAX(O2.orderid)
FROM Sales.Orders AS O2
WHERE O2.orderid < O1.orderid) AS prevorderid
FROM Sales.Orders AS O1;
SELECT orderid, orderdate, empid, custid,
(SELECT MIN(O2.orderid)
FROM Sales.Orders AS O2
WHERE O2.orderid > O1.orderid) AS nextorderid
FROM Sales.Orders AS O1;
---------------------------------------------------------------------
-- Running Aggregates
---------------------------------------------------------------------
SELECT orderyear, qty
FROM Sales.OrderTotalsByYear;
SELECT orderyear, qty,
(SELECT SUM(O2.qty)
FROM Sales.OrderTotalsByYear AS O2
WHERE O2.orderyear <= O1.orderyear) AS runqty
FROM Sales.OrderTotalsByYear AS O1
ORDER BY orderyear;
---------------------------------------------------------------------
-- Misbehaving Subqueries
---------------------------------------------------------------------
---------------------------------------------------------------------
-- NULL Trouble
---------------------------------------------------------------------
-- Customers who didn't place orders
-- Using NOT IN
SELECT custid, companyname
FROM Sales.Customers AS C
WHERE custid NOT IN(SELECT O.custid
FROM Sales.Orders AS O);
-- Add a row to the Orders table with a NULL custid
INSERT INTO Sales.Orders
(custid, empid, orderdate, requireddate, shippeddate, shipperid,
freight, shipname, shipaddress, shipcity, shipregion,
shippostalcode, shipcountry)
VALUES(NULL, 1, '20090212', '20090212',
'20090212', 1, 123.00, N'abc', N'abc', N'abc',
N'abc', N'abc', N'abc');
-- Following returns an empty set
SELECT custid, companyname
FROM Sales.Customers AS C
WHERE custid NOT IN(SELECT O.custid
FROM Sales.Orders AS O);
-- Exclude NULLs
SELECT custid, companyname
FROM Sales.Customers AS C
WHERE custid NOT IN(SELECT O.custid
FROM Sales.Orders AS O
WHERE O.custid IS NOT NULL);
-- Using NOT EXISTS
SELECT custid, companyname
FROM Sales.Customers AS C
WHERE NOT EXISTS
(SELECT *
FROM Sales.Orders AS O
WHERE O.custid = C.custid);
-- Cleanup
DELETE FROM Sales.Orders WHERE custid IS NULL;
DBCC CHECKIDENT('Sales.Orders', RESEED, 11077);
---------------------------------------------------------------------
-- Substitution Error in a Subquery Column Name
---------------------------------------------------------------------
-- Create and populate table Sales.MyShippers
IF OBJECT_ID('Sales.MyShippers', 'U') IS NOT NULL
DROP TABLE Sales.MyShippers;
CREATE TABLE Sales.MyShippers
(
shipper_id INT NOT NULL,
companyname NVARCHAR(40) NOT NULL,
phone NVARCHAR(24) NOT NULL,
CONSTRAINT PK_MyShippers PRIMARY KEY(shipper_id)
);
INSERT INTO Sales.MyShippers(shipper_id, companyname, phone)
VALUES(1, N'Shipper GVSUA', N'(503) 555-0137');
INSERT INTO Sales.MyShippers(shipper_id, companyname, phone)
VALUES(2, N'Shipper ETYNR', N'(425) 555-0136');
INSERT INTO Sales.MyShippers(shipper_id, companyname, phone)
VALUES(3, N'Shipper ZHISN', N'(415) 555-0138');
-- Shippers who shipped orders to customer 43
-- Bug
SELECT shipper_id, companyname
FROM Sales.MyShippers
WHERE shipper_id IN
(SELECT shipper_id
FROM Sales.Orders
WHERE custid = 43);
GO
-- The safe way using aliases, bug identified
SELECT shipper_id, companyname
FROM Sales.MyShippers
WHERE shipper_id IN
(SELECT O.shipper_id
FROM Sales.Orders AS O
WHERE O.custid = 43);
GO
-- Bug corrected
SELECT shipper_id, companyname
FROM Sales.MyShippers
WHERE shipper_id IN
(SELECT O.shipperid
FROM Sales.Orders AS O
WHERE O.custid = 43);
-- Cleanup
IF OBJECT_ID('Sales.MyShippers', 'U') IS NOT NULL
DROP TABLE Sales.MyShippers;
- Chapter 04 - Subqueries
- Chapter 04 - Subqueries - Exercises
- Chapter 04 - Subqueries - Solutions
- CHAPTER 7 Subqueries
- Subqueries
- Subqueries
- Misbehaving Subqueries (from "Inside MSSQL")
- Correlated Subqueries 相关子查询
- CHAPTER 04:EX 07
- CHAPTER 04:EX 18
- CHAPTER 04:EX 24
- CHAPTER 04:EX 25
- CHAPTER 05:EX 04
- Chapter 3-04
- Chapter 5-04
- Chapter 9-04
- Chapter 04 - 继承
- Chapter
- Chapter 03 - Joins
- Chapter 03 - Joins - Exercises
- OpenCV Tutorial 9 - Chapter 10
- Chapter 03 - Joins - Solutions
- 暑假集训总结 -- 持续更新
- Chapter 04 - Subqueries
- Chapter 04 - Subqueries - Exercises
- Chapter 04 - Subqueries - Solutions
- Chapter 05 - Table Expressions
- HDOJ3958期望
- Chapter 05 - Table Expressions - Exercises
- Chapter 05 - Table Expressions - Solutions
- Delphi用IdHTTP提交自定义Cookie
- Chapter 06 - Set Operations