2013-04-12 67 views
0

在SQL Server中,假设我们有一个SALES_HISTORY表,如下所示。按复杂查询SQL Server组

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

...并为每个购买每个客户的多条记录...

我如何写找到相应的查询:

对每一个客户,

  • 找到他在MOST购买的产品,
  • 找到该产品在他购买的所有产品中所占的百分比。

结果表必须有这样的列:

CustomerNo, 
MostPurchasedProductId, 
MostPurchasedProductPercentage 
+0

对于'CustomerNo' 1的示例会发生什么情况?我们应该为'MostPurchasedProductId'返回'productId' 12或14? – Lamak

+0

@siride不,它不是。讨论数据库服务器时,版本非常重要。例如,在SQL 2k或SQL 7中找不到某些功能(如row_number,partition by)。所以如果你想要一个明确的答案,比你应该有一个明确的问题。 – Marian

回答

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附带演示供您试用。

+0

非常感谢拉玛克。它帮助了很多。 –

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