2017-02-03 8 views
7

के साथ कुल गणना प्राप्त करें मुझे ग्राहक द्वारा दिए गए आदेशों की कुल गणना प्राप्त करने में सक्षम होना चाहिए, लेकिन एक प्रश्न में शीर्ष उत्पाद भी ढूंढना चाहिए। निम्नलिखित संरचना में उदाहरण के लिए,,एसक्यूएल सर्वर - शीर्ष 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 

लेकिन

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) 

मैं एक प्रश्न के साथ आए हैं के लिए, कि मुझे, परिणाम मैं देख रहा हूँ न जताए पॉल के लिए यह मुझे दे रहा है सही उत्पाद आईडी, लेकिन अकेले उस उत्पाद की गिनती।

मैं एक क्वेरी लौटना चाहते,

CustId | CustName | ProductId | TotalQty 
--------+---------------+---------------+------------ 
1  | Paul  | 1   | 3 
2  | F   | 1   | 1 
3  | Francis  | NULL  | NULL 

उत्तर

2

एक विकल्प संबंधों खंड के साथ

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 
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 
0

इसी तरह के प्रश्न का उत्तर एक अच्छा स्पष्टीकरण here

(यहां लाभ: उपयोग में शामिल होने की सामान्य अवधारणा) के साथ उत्तर दिया गया है। (नुकसान: क्वेरी बड़े रिकॉर्ड के लिए सक्षम नहीं हो सकता है) मैं अपने परिदृश्य

SELECT s.CustId, s.CustName, s.ProductId, m.TotalOrderTaken 
    FROM (SELECT p.CustId, p.CustName, t.ProductId, COUNT(*) AS ProductIdCount 
      FROM #Cust AS p 
      JOIN #Orders AS t 
      ON p.CustId = t.CustId 
     GROUP BY p.CustId, p.CustName, t.ProductId 
     ) AS s 
    JOIN (SELECT s.CustId, MAX(s.ProductIdCount) AS MaxProductIdCount, sum(s.ProductIdCount) TotalOrderTaken 
      FROM (
        SELECT p.CustId,p.CustName, t.ProductId, COUNT(*) AS ProductIdCount 
        FROM #Cust AS p 
        JOIN #Orders AS t 
        ON p.CustId = t.CustId 
       GROUP BY p.CustId, p.CustName, t.ProductId 
       ) AS s 
     GROUP BY s.CustId 
     ) AS m 
    ON s.CustId = m.CustId AND s.ProductIdCount = m.MaxProductIdCount 
-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 

परिणाम:

SQL सर्वर 2005 के बाद पर
+--------+----------+-----------+----------+ 
| CustId | CustName | ProductId | TotalQty | 
+--------+----------+-----------+----------+ 
|  1 | Paul  | 1   |  3 | 
|  2 | F  | 1   |  1 | 
|  3 | Francis | NULL  |  0 | 
+--------+----------+-----------+----------+ 
0

काम करता है।

;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 
संबंधित मुद्दे