SQL TOP 10销售的产品按itemno分组,按客户分组

时间:2018-05-28 13:03:13

标签: sql sql-server-2008 foreach distinct

我有一个包含以下内容的数据库:

Customerno,No_,Quantity

我想一次性为每位顾客退回十大最畅销产品......

我可以得到这样的TOP 10:

SELECT TOP 10 [No_],sum([Quantity]) as antal 
FROM orderlines
WHERE [Gen_ Prod_ Posting Group] = 'HANDEL' 
AND [Customerno] = 10001
GROUP BY [No_] 
HAVING sum([Quantity]) >= 2
ORDER BY sum([Quantity]) DESC

但我需要某种“foreach”,因为上述查询仅限于客户:10001

我希望它能循环使用不同的客户,所以我收到一份总清单

我知道的简单方法是制作一个

PHP中的SQL查询如下:

while($row = myssql_fetch_array(mssql_query(SELECT DISTINCT Customerno FROM orderlines)))
{

$new_query = ("SELECT TOP 10 [No_],sum([Quantity]) as antal 
FROM orderlines
WHERE [Customerno] = $row['customerno']
GROUP BY [No_] 
HAVING sum([Quantity]) >= 2
ORDER BY sum([Quantity]) DESC");


}

但是我觉得直接在SQL中做更有效率?

2 个答案:

答案 0 :(得分:1)

规范方法使用row_number()

SELECT cn.CustomerNo, cn.[No_], cn.antal
FROM (SELECT CustomerNo, [No_], SUM(Quantity) as antal,
             ROW_NUMBER() OVER (PARTITION BY CustomerNo ORDER BY SUM(Quantity) DESC) as seqnum
      FROM orderlines ol
      WHERE Gen_ Prod_ Posting Group = 'HANDEL' 
      GROUP BY CustomerNo, [No_] 
     ) cn
WHERE seqnum <= 10
ORDER BY CusterNo, antal DESC;

我删除了HAVING条件,因为这不是问题陈述的一部分。显然,您可以根据最低antal

进行过滤

答案 1 :(得分:0)

规范方式是使用ROW_NUMBER。但您可以使用OUTER APPLY来模拟For-each

SELECT DISTINCT Customerno, sub.*
FROM orderlines o
OUTER APPLY (SELECT TOP 10 [No_],sum([Quantity]) as antal 
             FROM orderlines o2
             WHERE [Gen_ Prod_ Posting Group] = 'HANDEL' 
                AND o.Customerno = o2.Customerno
             GROUP BY [No_] 
             HAVING sum([Quantity]) >= 2
             ORDER BY antal DESC
            ) AS sub
ORDER BY Customerno, sub.antal DESC