微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

sql – 获取每个类别的前10个产品

我有一个类似这样的查询
SELECT 
t.category,tc.product,tc.sub-product,count(*) as sales 
 FROM tg t,ttc tc
 WHERE t.value = tc.value
 GROUP BY t.category,tc.sub-product;

现在在我的查询中,我希望获得每个类别的前十大产品(按销售额排名),对于每个类别,我需要前5个子类别(按销售额排名)

您可以将问题陈述假设为:

根据销售情况获得每个类别的前10个产品,每个产品按销售额排名前5个子产品.

>此处类别可以是书籍
>产品可以是Harry Porter的书
>子产品可以是HarryPorter系列5

样本输入数据格式

category |product |subproduct |Sales [count (*)]

abc   test1    test11     120

abc   test1    test11     100

abc   test1    test11     10

abc   test1    test11     10

abc   test1    test11     10

abc   test1    test11     10

abc   test1    test12     10

abc   test1    test13     8

abc   test1    test14     6

abc   test1    test15     5

abc   test2    test21     80

abc   test2    test22     60

abc   test3    test31     50

abc   test3    test32     40

abc   test4    test41     30

abc   test4    test42     20

abc   test5    test51     10

abc   test5    test52     5 

abc   test6    test61     5 

|

|

|

bcd   test2    test22     10 

xyz   test3    test31     5 

xyz   test3    test32     3 

xyz   test4    test41     2

输出将是“

top 5 rf for (abc) -> abc,test1(289) abc,test2 (140),abc test3 (90),abc test4(50),abc test5 (15)

top 5 rfm for (abc,test1) -> test11(260),test12(10),test13(8),test14(6),test15(5) and so on

我的查询失败了,因为结果真的很大.我正在阅读像甲骨文这样的oracle分析函数.有人可以帮助我使用分析函数修改查询.任何其他方法也可以工作.

我指的是这个http://www.orafaq.com/node/55.但是无法为此获得正确的SQL查询.

任何帮助将不胜感激.我喜欢在这上面坚持2天:(

解决方法

可能有理由不使用分析函数,而是单独使用分析函数
select am,rf,rfm,rownum_rf2,rownum_rfm
from
(
    -- the 3nd level takes the subproduct ranks,and for each equally ranked
    -- subproduct,it produces the product ranking
    select am,rownum_rfm,row_number() over (partition by rownum_rfm order by rownum_rf) rownum_rf2
    from
    (
        -- the 2nd level ranks (without ties) the products within
        -- categories,and subproducts within products simultaneosly
        select am,row_number() over (partition by am order by count_rf desc) rownum_rf,row_number() over (partition by am,rf order by count_rfm desc) rownum_rfm
        from
        (
            -- inner most query counts the records by subproduct
            -- using regular group-by. at the same time,it uses
            -- the analytical sum() over to get the counts by product
            select tg.am,ttc.rf,ttc.rfm,count(*) count_rfm,sum(count(*)) over (partition by tg.am,ttc.rf) count_rf
            from tg inner join ttc on tg.value = ttc.value
            group by tg.am,ttc.rfm
        ) X
    ) Y
    -- at level 3,we drop all but the top 5 subproducts per product
    where rownum_rfm <= 5   -- top  5 subproducts
) Z
-- the filter on the final query retains only the top 10 products
where rownum_rf2 <= 10  -- top 10 products
order by am,rownum_rfm;

我使用的是rownum而不是rank,所以你永远不会得到关系,换句话说,关系会随机决定.如果数据不够密集(在前10个产品中的任何一个产品中少于5个副产品 – 它可能显示来自其他一些产品的副产品),这也不起作用.但是如果数据密集(大型建立的数据库),查询应该可以正常工作.

下面两次传递数据,但在每种情况下返回正确的结果.同样,这是一个无排名查询.

select am,count_rf,count_rfm,rownum_rf,rownum_rfm
from
(
    -- next join the top 10 products to the data again to get
    -- the subproduct counts
    select tg.am,tg.rf,tg.count_rf,tg.rownum_rf,ROW_NUMBER() over (partition by tg.am,tg.rf order by 1 desc) rownum_rfm
    from (
        -- first rank all the products
        select tg.am,tg.value,count(*) count_rf,ROW_NUMBER() over (order by 1 desc) rownum_rf
        from tg
        inner join ttc on tg.value = ttc.value
        group by tg.am,ttc.rf
        order by count_rf desc
        ) tg
    inner join ttc on tg.value = ttc.value and tg.rf = ttc.rf
    -- filter the inner query for the top 10 products only
    where rownum_rf <= 10
    group by tg.am,tg.rownum_rf
) X
-- filter where the subproduct rank is in top 5
where rownum_rfm <= 5
order by am,rownum_rfm;

列:

count_rf : count of sales by product
count_rfm : count of sales by subproduct
rownum_rf : product rank within category (rownumber - without ties)
rownum_rfm : subproduct rank within product (without ties)

原文地址:https://www.jb51.cc/mssql/83506.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐