-3

可能重复:
获取每个类别的前 10 名产品

我正在寻找一个 Oracle 查询来获得前 5000 家商店,并为每家商店获得前 10 名产品,并为每个前 10 名产品获得前 5 名子产品。所以我总共应该得到 5000*10*5 行。

有人可以帮助我使用 Oracle 的分析功能得到这个。

我当前的查询看起来像

SELECT 
store,
product, 
sub-product,
 count(*) as sales 
 FROM stores_data
 GROUP BY store, product, sub-product;

请假设表名为 stores_data 列 store_id 、 product、sub_product

4

2 回答 2

4

您应该使用 dense_rank 来获取前 N 行。

就像是

SELECT
  storeid,
  store,
  productid,
  product,
  subproductid,
  subproduct
FROM
  (
    SELECT
      s.storeid,
      s.store,
      p.productid,
      p.product,
      sp.subproductid,
      sp.subproduct,
      dense_rank() over ( order by s.storeid) as storerank,
      dense_rank() over ( partition by s.storeid 
                          order by p.productid) as productrank
      dense_rank() over ( partition by s.storeid, p.productid 
                          order by sp.subproductid) as productrank
    FROM
      stores s
      INNER JOIN products p on p.storeid = s.storeid
      INNER JOIN subproduct sp on sp.productid = p.productid
  ) t
WHERE
  t.storerank <= 5000 and
  t.productrank < 10 and
  t.subproductrank < 5

当然,我现在不知道您的表格,也不知道它们之间的关系。以及您要检查的实际字段和条件,所以这只是一个简单的查询,根据它们的 id 获取前 N 条记录。此外,此查询希望产品只有一个商店,但情况可能并非如此。至少它会向您展示如何使用dense_rank来获得三层排序/过滤。

于 2011-02-14T07:22:44.680 回答
1

我会留下另一个答案,因为我认为这看起来更像是这样的表结构

但是您在另一个线程中描述了一个如下所示的表:

create table store_data (
  store varchar2(40), 
  product varchar2(40), 
  subproduct varchar2(40), 
  sales int);

这实际上看起来像是已经聚合的数据,您现在确实想要再次分析。您的查询可能如下所示。它首先汇总销售额的总和,因此您也可以按销售额订购商店和产品(表中的销售额似乎是针对子产品的。之后,您可以按销售额为商店和产品添加排名。我添加了一个对子产品也进行排名。我在这里使用了排名,所以当更多记录具有相同的销售额时,编号会有差距。这样,当您获得 8 条排名为 1 的记录时,因为它们都具有相同的销售额,第 6 条记录实际上排名 9 而不是 2,因此您将只选择 8 家顶级商店(您想要 5 家,但如果它们实际上销售完全相同,为什么要跳过其他 3 家)而不是其他 4 家。

select
  ts.*
from  
  (
    select
      ss.*,
      rank() over (order by storesales) as storerank,
      rank() over (partition by store order by productsales) as productrank,
      rank() over (partition by store, product order by subproductsales) as subproductrank
    from
      (
        select 
          sd.*,
          sum(sales) over (partition by store) as STORESALES,
          sum(sales) over (partition by store, product) as PRODUCTSALES,
          sum(sales) over (partition by store, product, subproduct) as SUBPRODUCTSALES
        from 
          store_data sd
      ) ss 
  ) ts
where
  ts.storerank <= 2 and
  ts.productrank <= 3 and
  ts.subproductrank <= 4      
于 2011-02-14T09:12:53.717 回答