我需要能够找到客户下达的订单总数,还可以在一个查询中找到最佳产品。例如,在以下结构中,
CREATE TABLE #Cust (CustId INT, CustName VARCHAR(50))
CREATE TABLE #Product (ProductId INT, ProductName VARCHAR(10) )
CREATE TABLE #Orders (CustId INT, ProductId INT, OrderTaken BIT)
INSERT #Cust
( CustId, CustName )
VALUES ( 1, 'Paul' ),
( 2, 'F' ),
( 3, 'Francis' )
INSERT #Product
( ProductId, ProductName )
VALUES ( 1, 'Table' ),
( 2, 'Chair' )
INSERT #Orders
( CustId, ProductId, OrderTaken )
VALUES ( 1, 1, 1 ),
( 1, 1, 1 ),
( 1, 2, 1 ),
( 2, 1, 1 )
我想出了一个查询,
SELECT * FROM #Cust AS C OUTER APPLY
(
SELECT TOP 1 SQ.ProductId, SUM(SQ.TotalCount) AS TotalQty FROM
(
SELECT O.ProductId, COUNT(*) TotalCount
FROM #Orders AS O WHERE O.CustId = C.CustId
GROUP BY O.CustId , O.ProductId
) SQ
GROUP BY SQ.ProductId
) X
但是,这并没有给我我想要的结果,因为Paul给了我正确的ProductId,但仅仅是那个产品的数量。
我想要一个Query返回,
CustId | CustName | ProductId | TotalQty
--------+---------------+---------------+------------
1 | Paul | 1 | 3
2 | F | 1 | 1
3 | Francis | NULL | NULL
答案 0 :(得分:2)
一个选项是使用WITH TiES子句
Select Top 1 with ties
CustID
,CustName
,ProductId
,TotalQty
From (
Select C.CustID
,C.CustName
,O.ProductId
,TotalQty = count(O.CustId) over (Partition By O.CustID)
,ProdCount = count(O.CustId) over (Partition By O.CustID,O.ProductID)
From #Cust C
Left Join #Orders O on C.CustID=O.CustId
) A
Order by Row_Number() over (Partition By CustID Order by ProdCount Desc)
返回
CustID CustName ProductId TotalQty
1 Paul 1 3
2 F 1 1
3 Francis NULL 0
答案 1 :(得分:0)
尝试
SELECT c.*, ProductId, CustProdTotal, CustTotal
FROM #Cust AS C
OUTER APPLY (
select top(1) with ties ProductId, CustProdTotal, CustTotal
from (
select *, count(OrderTaken) over() as CustTotal
, count(OrderTaken) over(partition by ProductId) as CustProdTotal
from #Orders o
where O.CustId = C.CustId) x
order by row_number() over(order by CustProdTotal desc)
) z
答案 2 :(得分:0)
答案 3 :(得分:0)
适用于SQL Server 2005及以上版本。
;with cte1 as (select c.custid, c.custname, o.productid, count(*) as TotalQty
from #cust c
left join #orders o on c.custid=o.custid
left join #product p on p.productid=o.productid
group by c.custid, c.custname, o.productid)
,cte2 as (select custid, max(TotalQty) as TopQty
from cte1
group by custid)
Select cte1.*
from cte1
inner join cte2 on cte1.custid=cte2.custid and cte1.TotalQty=cte2.Topqty
答案 4 :(得分:-1)
如果您不能使用over
子句,这将有效(显然,与over
子句相比,工作量更多):
SELECT custOrderAll.CustId
, custOrderAll.CustName
, MaxOrder.ProductId
, MAX(custOrderAll.cntAll) TotalQty
FROM (
SELECT c.CustId
, c.CustName
, COUNT(O.ProductId) cntAll
FROM #Cust AS C
LEFT JOIN #Orders AS O
ON O.CustId = C.CustId
GROUP BY c.CustId
, c.CustName
) custOrderAll
LEFT JOIN (
SELECT custOrderMAX.CustId
, custOrderMAX.CustName
, custOrderMAX.ProductId
FROM (
SELECT c.CustId
, c.CustName
, O.ProductId
, COUNT(O.ProductId) cntMax
FROM #Cust AS C
LEFT JOIN #Orders AS O
ON O.CustId = C.CustId
GROUP BY c.CustId
, c.CustName
, O.ProductId
) custOrderMAX
INNER JOIN (
SELECT mxCnt.CustId
, mxCnt.CustName
, MAX(mxCnt.cntMax) mxCnt
FROM (
SELECT c.CustId
, c.CustName
, O.ProductId
, COUNT(O.ProductId) cntMax
FROM #Cust AS C
LEFT JOIN #Orders AS O
ON O.CustId = C.CustId
GROUP BY c.CustId
, c.CustName
, O.ProductId
) mxCnt
GROUP BY mxCnt.CustId
, mxCnt.CustName
) custOrderMAXCnt
ON custOrderMAXCnt.CustId = custOrderMAX.CustId
AND custOrderMAXCnt.mxCnt = custOrderMAX.cntMax
) MaxOrder
ON MaxOrder.CustId = custOrderAll.CustId
AND MaxOrder.CustName = custOrderAll.CustName
GROUP BY custOrderAll.CustId
, custOrderAll.CustName
, MaxOrder.ProductId
结果:
+--------+----------+-----------+----------+
| CustId | CustName | ProductId | TotalQty |
+--------+----------+-----------+----------+
| 1 | Paul | 1 | 3 |
| 2 | F | 1 | 1 |
| 3 | Francis | NULL | 0 |
+--------+----------+-----------+----------+