查找集合中每个分组的排名最高的唯一项目

时间:2015-08-05 21:54:50

标签: sql-server tsql sql-server-2012

鉴于以下数据集包含一系列客户产品,以及每个产品的大量相关产品,我想为每个产品ID选择排名最高的唯一相关产品ID。

样本数据

此表显示单个客户的数据。会有多个客户。

以黄色选择的项目是此示例客户ID的结果示例。

SQL example dataset

因此,单个产品ID可能包含多个相关产品ID。对于具有6个产品ID的单个客户,我想为每个产品ID返回排名最高的相关产品ID。

规则

问题是,我希望尽可能地消除重复。因此,如果相同的相关产品ID在多个产品ID中排名最高,则选择应向下移动到排名第二的相关产品ID。

目标是尽可能为每个产品ID提供唯一的(在每个客户ID内)相关产品ID。

如果无法选择唯一的相关产品ID(因为只有重复的相关产品ID可用),则应选择排名靠前的。

结果

对于产品2,相关产品ID 23194排名最高,但它不是唯一的,因此被跳过以支持23287.对于产品4,我们可以使用23194或23300,但因为两者都不是唯一的,我们获得排名最高的项目。

我尝试使用递归CTE执行此操作,但这将迭代这些项目并在第一个产品上分配相关产品,然后查明相关产品是否在集合中稍后重复。

我还能怎样处理这个问题?

1 个答案:

答案 0 :(得分:2)

您可以使用ROW_NUMBERCOUNT OVER()

SQL Fiddle

;WITH Cte AS(
    SELECT *,
        RN = (RelatedProductRanking  + COUNT(*) OVER(PARTITION BY ProductID)) * 
                COUNT(*) OVER(PARTITION BY RelatedProductID)
    FROM tbl    
),
CteRnk AS(
    SELECT *,
        RNK = ROW_NUMBER() OVER(PARTITION BY ProductID ORDER BY RN)
    FROM Cte
)
SELECT 
    CustomerID, ProductRanking, ProductID, RelatedProductRanking, RelatedProductID
FROM CteRnk
WHERE RNK = 1
ORDER BY ProductRanking, RelatedProductRanking

<强> RESULT

| CustomerID | ProductRanking | ProductID | RelatedProductRanking | RelatedProductID |
|------------|----------------|-----------|-----------------------|------------------|
|      12436 |              1 |     14553 |                     1 |            14481 |
|      12436 |              2 |     33017 |                     2 |            23287 |
|      12436 |              3 |     14203 |                     1 |            14289 |
|      12436 |              4 |     23038 |                     1 |            23194 |
|      12436 |              5 |     15120 |                     1 |            14520 |
|      12436 |              6 |     23014 |                     1 |            23300 |