我想找到每个客户购买的最常用的产品。我的数据集是这样的:
CustomerID ProdID FavouriteProduct
1 A ?
1 A ?
1 A ?
1 B ?
1 A ?
1 A ?
1 A ?
1 B ?
2 A ?
2 AN ?
2 G ?
2 C ?
2 C ?
2 F ?
2 D ?
2 C ?
产品太多了,所以我不能将它们放在数据透视表中。
答案看起来像这样:
CustomerID ProdID FavouriteProduct
1 A A
1 A A
1 A A
1 B A
1 A A
1 A A
1 A A
1 B A
2 A C
2 AN C
2 G C
2 C C
2 C C
2 F C
2 D C
2 C C
查询可能如下所示:
Update table
set FavouriteProduct = (Select
CustomerID, Product, Max(Count(Product))
From Table
group by CustomerID, Product) FP
答案 0 :(得分:2)
获得最常用产品的另一种方法是使用row_number()
:
select customerid, productid,
max(case when seqnum = 1 then productid end) over (partition by customerid) as favoriteproductid
from (select customerid, productid, count(*) as cnt,
row_number() over (partition by customerid order by count(*) desc) as seqnum
from customer c
group by customerid, productid
) cp;
答案 1 :(得分:2)
要完全按照问题中的描述返回行,您可以尝试使用表格表达式(我在我的示例中使用CTE)首先返回流行度排名,其中数字越大,产品越受欢迎为每个客户。
WITH RankTable AS (
SELECT
CustomerID, ProductID, COUNT(*) AS Popularity
FROM TableA
GROUP BY CustomerID, ProductID
)
然后可以通过首先在原始表(TableA)和表表达式(RankTable)上执行内部联接,然后使用窗口函数在FavoriteProduct列中创建值来返回完整结果表。
SELECT
P.CustomerID
, P.ProductID
, FIRST_VALUE(P.ProductID) OVER(
PARTITION BY R.CustomerID
ORDER BY R.Popularity DESC, R.ProductID) AS FavoriteProduct
FROM TableA AS P
INNER JOIN RankTable AS R
ON P.CustomerID = R.CustomerID
AND P.ProductID= R.ProductID;
答案 2 :(得分:1)
感谢尼克,我找到了找到最常见价值的方法。我与你分享它是如何运作的:
Select CustomerID,ProductID,Count(*) as Number
from table A
group by CustomerID,ProductID
having Count(*)>= (Select Max(Number) from (Select CustomerID,ProductID,Count(*) as Number from table B where B.CustomerID= A.CustomerID group by CustomerID,Product)C)
答案 3 :(得分:1)
如果您的SQL执行速度不够快而且客户也在较小的表中,这可能会更好用::
select C.CustomerId, R.ProductID
from Customer C
outer apply (
Select top 1 ProductID,Count(*) as Number
from table A
where A.CustomerId = C.CustomerId
group by ProductId
order by Number desc
) R
答案 4 :(得分:1)
这一个,基于本页末尾的示例:http://www.sql-server-performance.com/2006/find-frequent-values/可能会更快:
SELECT CustomerID, ProdID, Cnt
FROM
(
SELECT CustomerID, ProdID, COUNT(*) as Cnt,
RANK() OVER (
PARTITION BY CustomerID
ORDER BY COUNT(*) DESC
) AS Rnk
FROM YourTransactionTable
GROUP BY CustomerID, ProdID
) x
WHERE Rnk = 1
这个使用RANK()
函数。在这种情况下,您不必加入同一个表(意味着需要的工作少得多)
现在要更新现有数据,我喜欢将我的数据集包装在WITH中,以使调试更容易,最后的更新更简单:
;WITH
(
SELECT CustomerID, ProdID, Cnt
FROM
(
SELECT CustomerID, ProdID, COUNT(*) as Cnt,
RANK() OVER (PARTITION BY CustomerID
ORDER BY COUNT(*) DESC) AS Rnk
FROM TransactionTable
GROUP BY CustomerID, ProdID
) x
WHERE Rnk = 1
) As SRC
UPDATE FavouriteTable
SET Favourite = SRC.ProdID
FROM SRC
WHERE SRC.CustomerID = Favourite.CustomerID