--获取订单号最大的订单的信息
DECLARE @maxid INT = (SELECT MAX(orderid) FROM Sales.Orders)
SELECT orderid,orderdate,empid,custid
FROM Sales.Orders
WHERE orderid = @maxid
#嵌入式代码实现-标量子查询
SELECT orderid,orderdate,empid,custid
FROM Sales.Orders
WHERE orderid = (SELECT MAX(orderid) FROM Sales.Orders)
#标量子查询返回多个值,查询会失效
--返回有姓氏以字母B开头的任意雇员的订单id
SELECT E.empid FROM HR.Employees AS E
WHERE E.lastname LIKE N'B%'
#先执行以上内容,发现以B开头的雇员只有一个,所以以下执行正常
SELECT orderid
FROM Sales.Orders
WHERE empid = (SELECT E.empid FROM HR.Employees AS E
WHERE E.lastname LIKE N'B%')
--返回有姓氏中含有a的雇员的订单id
SELECT E.empid FROM HR.Employees AS E
WHERE E.lastname LIKE N'%a%'
#先执行以上代码发现姓氏中有a的雇员有三个所以导致下面查询无效
SELECT orderid
FROM Sales.Orders
WHERE empid = (SELECT E.empid FROM HR.Employees AS E
WHERE E.lastname LIKE N'%a%')
--返回姓氏以D开头的雇员所在的订单号
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 Sales.Orders AS O JOIN HR.Employees AS E
ON O.empid = E.empid
WHERE E.lastname LIKE N'D%'
--返回有美国客户的订单id
SELECT *
FROM Sales.Orders AS O
WHERE O.custid IN (
SELECT
C.custid
FROM Sales.Customers AS C
WHERE C.country = 'USA'
)
#NOT IN 即可查询非美国用户
SELECT *
FROM Sales.Orders AS O
WHERE O.custid NOT IN (
SELECT
C.custid
FROM Sales.Customers AS C
WHERE C.country = 'USA'
)
--创建一个dbo.Orders表 里面存储Sales.Orders中偶数的订单号
CREATE TABLE dbo.Orders(orderid INT NOT NULL CONSTRAINT PK_Orders PRIMARY KEY);
INSERT INTO dbo.Orders(orderid)
SELECT orderid
FROM Sales.Orders
WHERE orderid % 2 = 0
--获取dbo.Nums表中介于dbo.Orders表中订单号最大与最小之间的值且不存在于dbo.Orders表中
--其实最终结果就是Sales.Orders表中订单号为单数的订单号
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)
--先从O1中取一个custid在子查询中获取这个custid的最大orderid·
SELECT
custid,orderid,orderdate,empid
FROM Sales.Orders AS O1
WHERE O1.orderid = (
SELECT
MAX(O2.orderid)
FROM Sales.Orders AS O2
WHERE O2.custid = O1.custid
)
--从O1取一行数据,然后根据这行查询结果的custid在子查询中获取这个用户的的所有订单值的总和,用这行查询的订单值除以总的订单值再乘100获取这个订单值在用户总订单值中的百分比占比
--CAST(....AS NUMERIC(5,2))表示这个百分比占比总共有五位其中小数点后占了两位符合百分比的规则
SELECT
orderid,custid,val,
CAST(100. * O1.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
#下面是查询结果将custid = 1或2的pct值相加结果是100
orderid custid val pct
----------- ----------- --------------------------------------- -----------------
10643 1 814.50 19.06
10692 1 878.00 20.55
10702 1 330.00 7.72
10835 1 845.80 19.79
10952 1 471.20 11.03
11011 1 933.50 21.85
10308 2 88.80 6.33
10625 2 479.75 34.20
10759 2 320.00 22.81
10926 2 514.40 36.67
10365 3 403.20 5.74
谓词EXISTS
可接受一个查询作为输入。如果子查询作为任意行,谓词返回true
否则返回false
--先获取一个西班牙客户的的信息,然后判断这个西班牙客户是否有订单存在,有的话返回客户信息
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
)
--O1先查询出一行然后在O2中查询在O1订单之前运费最高额
--返回的结果就是每一单之前的运费最高额
SELECT
orderid,orderdate,empid,custid,
(
SELECT
MAX(freight)
FROM Sales.Orders AS O2
WHERE O2.orderdate < O1.orderdate
)AS premaxfreight
FROM Sales.Orders AS O1
运行聚合是随着时间积累值得聚合
--返回每年和之前总的qty,最后按照年排序
SELECT
orderyear,qty,
(
SELECT
SUM(O2.qty)
FROM Sales.OrderTotalsByYear AS O2
WHERE O2.orderyear <= O2.orderyear
) AS runqty
FROM Sales.OrderTotalsByYear AS O1
ORDER BY orderyear
--4.5.1
#活动最后一天下得所有订单
SELECT
orderid,orderdate,custid,empid
FROM Sales.Orders AS O1
WHERE O1.orderdate = (
SELECT
MAX(O2.orderdate)
FROM Sales.Orders AS O2
)
--4.5.2
#查询数量最多的客户的所有订单
#最内层用TOP查询订单最多的有多少单,次内层根据订单数量将选出有这么多订单的用户id,最外层根据用户id将他们所有的订单信息查出来
SELECT
custid,orderid,orderdate,empid
FROM Sales.Orders AS O1
WHERE O1.custid IN (
SELECT
custid
FROM Sales.Orders AS O2
GROUP BY custid
HAVING COUNT(O2.orderid) = (
SELECT
TOP(1) WITH TIES COUNT(O3.orderid)
FROM Sales.Orders AS O3
GROUP BY O3.custid
ORDER BY COUNT(O3.orderid) DESC
)
)
--4.5.3
#返回2008年5月1日或之后没有下单的雇员
SELECT
empid,firstname,lastname
FROM HR.Employees
WHERE empid NOT IN (
SELECT
empid
FROM Sales.Orders
WHERE orderdate > '20080501'
)
--4.5.4
#返回有客户但是没有雇员的国家
SELECT
DISTINCT country
FROM Sales.Customers
WHERE country NOT IN (
SELECT
country
FROM HR.Employees
)
--4.5.5
#返回客户活动最后一天下的所有订单
SELECT
custid,orderid,orderdate ,empid
FROM Sales.Orders AS O1
WHERE orderdate = (
SELECT
MAX(O2.orderdate)
FROM Sales.Orders AS O2
WHERE O1.custid = O2.custid
)
--4.5.6
#返回2007年下单但是2008年没有下单的客户
SELECT
custid,companyname
FROM Sales.Customers
WHERE custid IN (
SELECT
custid
FROM Sales.Orders
WHERE orderdate >= '20070101' AND orderdate < '20080101'
) AND custid NOT IN(
SELECT
custid
FROM Sales.Orders
WHERE orderdate >= '20080101' AND orderdate < '20090101'
)
--4.5.7
#返回订购了产品12的用户
SELECT
DISTINCT
C.custid,companyname
FROM Sales.Customers AS C JOIN Sales.Orders AS O ON C.custid = O.custid
WHERE orderid IN(
SELECT
orderid
FROM Sales.OrderDetails
WHERE productid = 12
)
#使用exists的另一种方法
SELECT
custid,companyname
FROM Sales.Customers AS C
WHERE EXISTS(
SELECT
custid
FROM Sales.Orders AS O
WHERE C.custid = O.custid AND EXISTS(
SELECT
*
FROM Sales.OrderDetails AS OD
WHERE productid = 12 AND O.orderid = OD.orderid
)
)
--4.5.7
SELECT
custid,ordermonth,qty,(
SELECT
SUM(CO2.qty)
FROM Sales.CustOrders AS CO2
WHERE CO1.custid = CO2.custid
AND CO2.ordermonth <= CO1.ordermonth
)
FROM Sales.CustOrders AS CO1
ORDER BY custid,ordermonth