SQL Server组按复杂查询

时间:2013-04-12 15:01:29

标签: sql sql-server group-by row-number

在SQL Server中,假设我们有一个SALES_HISTORY表,如下所示。

CustomerNo  PurchaseDate    ProductId
    1         20120411         12
    1         20120330         13
    2         20120312         14
    3         20120222         16
    3         20120109         16

......以及每位顾客每次购买的许多记录......

如何编写适当的查询以查找:

对于每个客户,

  • 找到他在MOST购买的产品,
  • 查找此产品占其购买产品的百分比。

结果表必须包含以下列:

CustomerNo, 
MostPurchasedProductId, 
MostPurchasedProductPercentage

2 个答案:

答案 0 :(得分:1)

假设SQL Server 2005+,您可以执行以下操作:

;WITH CTE AS
(
    SELECT *, 
           COUNT(*) OVER(PARTITION BY CustomerNo, ProductId) TotalProduct,
           COUNT(*) OVER(PARTITION BY CustomerNo) Total
    FROM YourTable
), CTE2 AS
(
    SELECT *,
           RN = ROW_NUMBER() OVER(PARTITION BY CustomerNo 
                                  ORDER BY TotalProduct DESC)
    FROM CTE
)
SELECT CustomerNo, 
       ProductId MostPurchasedProductId, 
       CAST(TotalProduct AS NUMERIC(16,2))/Total*100 MostPurchasedProductPercent
FROM CTE2
WHERE RN = 1

当您购买的产品数量最多时,您仍然需要处理。 Here is a sqlfiddle有一个演示供您试用。

答案 1 :(得分:0)

可以做得更漂亮,但确实有效:

with cte   as(
select CustomerNo, ProductId, count(1) as c
from SALES_HISTORY
group by CustomerNo, ProductId)

select CustomerNo, ProductId as MostPurchasedProductId, (t.c * 1.0)/(select sum(c) from cte t2 where t.CustomerNo = t2.CustomerNo) as MostPurchasedProductPercentage
from cte t
where c = (select max(c) from cte t2 where t.CustomerNo = t2.CustomerNo)

SQL Fiddle