sql >> Databáze >  >> RDS >> Oracle

Získejte 10 nejlepších produktů pro každou kategorii

Pravděpodobně existují důvody, proč nepoužívat analytické funkce, ale používat analytické funkce samostatně :

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, rf, rfm, 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, rf, rfm,
          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.rf, 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_rf2, rownum_rfm;

Použil jsem rownum místo hodnosti, takže nikdy nezískáte remízu, nebo jinými slovy, o remíze se rozhodne náhodně. To také nefunguje, pokud data nejsou dostatečně hustá (méně než 5 dílčích produktů v některém z 10 nejlepších produktů – místo toho mohou zobrazovat dílčí produkty z některých jiných produktů). Ale pokud jsou data hustá (velká zavedená databáze), dotaz by měl fungovat dobře.

Níže uvedený postup provede dva průchody dat, ale v každém případě vrátí správné výsledky. Opět se jedná o dotaz na hodnocení bez vazeb.
select am, rf, rfm, 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, ttc.rfm, tg.count_rf, tg.rownum_rf, count(*) count_rfm,
        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, ttc.rf, 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, tg.value, 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.rf, ttc.rfm, tg.count_rf, tg.rownum_rf
) X
-- filter where the subproduct rank is in top 5
where rownum_rfm <= 5
order by am, rownum_rf, rownum_rfm;

sloupce:

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)


  1. Laravel + Vagrant =Přístup odepřen pro uživatele 'root'@'localhost'

  2. cc1:chyba:nerozpoznaná možnost příkazového řádku -Wno-null-conversion během instalace python-mysql na mac 10.7.5

  3. Chyba serveru SQL 4104:Vícedílný identifikátor nelze svázat.

  4. SQL:vyhledat/nahradit, ale pouze při prvním zobrazení hodnoty v záznamu