5

我想为每个标签提取不同产品类别的前 3 名畅销产品。数据如下所示:

tag  | product_name | product_category | order_count
tag1 | product1     | category1        | 100
tag1 | product2     | category2        | 80
tag1 | product3     | category2        | 60
tag1 | product4     | category3        | 50
......

我知道如何使用 ROW_NUMBER() 提取每个标签的前 3 个畅销产品,但它会返回 product1、product2、product3。我不想要 product3,因为它与 product2 属于同一类别。我想要 product4 代替。如何在 SQL Server 中执行此操作?

4

3 回答 3

4

第一个 ROW_NUMBER 删除每个标签和 product_category 的重复行,第二个 ROW_NUMBER 选择每个标签的前 3 个畅销产品

;WITH cte AS
 (SELECT *, ROW_NUMBER() OVER(PARTITION BY tag, product_category ORDER BY order_count DESC) AS rn
  FROM yourtable
  ), cte2 AS
  (SELECT *, ROW_NUMBER() OVER(PARTITION BY tag ORDER BY order_count DESC) AS rn2
   FROM cte
   WHERE rn = 1
   )
   SELECT *
   FROM cte2
   WHERE rn2 <= 3

演示SQLFiddle

下一个使用派生表

;WITH cte AS
 (SELECT t2.tag, t2.product_name, t2.product_category, t2.order_count,
         ROW_NUMBER() OVER(PARTITION BY t2.tag ORDER BY order_count DESC) AS rn
  FROM (SELECT tag, product_category, MAX(order_count) AS maxCount
        FROM yourtable
        GROUP BY tag, product_category
        ) t1 JOIN yourtable t2 ON t1.tag = t2.tag 
          AND t1.product_category = t2.product_category
          AND maxCount = order_count
  )
  SELECT *
  FROM cte
  WHERE rn <= 3

演示SQLFiddle

于 2013-11-02T08:26:02.113 回答
3

只要您使用 ,您就可以使用RANK()( 或) 。假设您使用的是 SQL Server 2005+ ,这结合起来应该可以很好地工作:ROW_NUMBER()PARTITION BYTOP()

with cte as (
  select tag, 
    product_name, 
    product_category, 
    order_count, 
    rank() over (partition by product_category 
                 order by product_category, order_count desc) rnk
  from yourtable
  )
select top 3 tag, product_name, product_category, order_count
from cte 
where rnk = 1
order by order_count desc

这将产生以下内容:

TAG     PRODUCT_NAME   PRODUCT_CATEGORY  ORDER_COUNT
tag1    product1       category1         100
tag1    product2       category2         80
tag1    product4       category3         50
于 2013-11-02T00:29:17.103 回答
0

我建议只选择一个

declare @t table (
    tag                 varchar(10),
    product_name        varchar(10),
    product_category    varchar(10),
    order_count         int
);

insert into @t values
('tag1', 'product1', 'category1', 100),
('tag1', 'product2', 'category2', 80 ),
('tag1', 'product3', 'category2', 60 ),
('tag1', 'product4', 'category3', 50 ),
('tag1', 'product5', 'category4', 40 );


select top 3
    *
from
    @t
order by
    row_number() over(partition by product_category order by order_count desc), 
    order_count desc;

SQL小提琴

于 2014-12-26T16:06:44.527 回答