简体   繁体   中英

MAX values over partition by ()

I have monthly sales over specific car brands, and every month i want the max 5 car brands in relation to the sales. Then, next to each of these max brands, i want the number (if there is) that indicates how many times this specific brand was in the top five the previous 4 months.

Foe example, if table data is:

Timestamp | Brand | Sales
1/1/2012  | A     | 23
1/1/2012  | B     | 45
1/1/2012  | C     | 11
1/1/2012  | D     | 3
1/1/2012  | E     | 55
1/1/2012  | F     | 1
1/1/2012  | G     | 22
---------------------------
1/2/2012  | A     | 93
1/2/2012  | B     | 35
1/2/2012  | C     | 01
1/2/2012  | D     | 100
1/2/2012  | E     | 45
1/2/2012  | F     | 77
1/2/2012  | G     | 12

for a two month data, the query output for February (examining only Feb and Jan) would be :

Max_ Brand_Sales| Reappearance_Factor
--------------------------------------
E               | 1
B               | 1
D               | 0
F               | 0
A               | 1
Select
  c.Brand,
  nvl(Count(p.Brand), 0) As Reappearance_Factor
From (
  Select
    Brand,
    Rank () Over (Order By Sales Desc) as r
  From
    Sales
  Where
    Timestamp = Date '2012-02-01'
  ) c
    left outer join (
  Select
    Brand,
    Rank () Over (Partition By Timestamp Order By Sales Desc) as r
  From
    Sales
  Where
    Timestamp >= Date '2011-10-01' And
    Timestamp < Date '2012-02-01'
  ) p
  on c.Brand = p.Brand And p.r <= 5
Where
  c.r <= 5
Group By
  c.Brand

http://sqlfiddle.com/#!4/46770/21

Try this:

1) Query that calculates monthly rank for every brand:

SELECT
  s.Brand,
  trunc(s.Timestamp,'MONTH') month_start,
  rank() OVER (PARTITION BY trunc(s.Timestamp,'MONTH') 
               ORDER BY s.Sales DESC) as monthly_rank
FROM Sales s;

2) Query that outputs the top 5 brands for current month:

SELECT
 t.Brand
FROM
(
  SELECT
    s.Brand,
    trunc(s.Timestamp,'MONTH') month_start,
    rank() OVER (PARTITION BY trunc(s.Timestamp,'MONTH') 
                 ORDER BY s.Sales DESC) as monthly_rank
  FROM Sales s
) t
WHERE monthly_rank <= 5
  AND month_start = trunc(sysdate,'MONTH');

3) Query to calculate "Reappearance" for past 4 month

SELECT
 t.Brand,
 count(*) as top
FROM
(
  SELECT
    s.Brand,
    trunc(s.Timestamp,'MONTH') month_start,
    rank() OVER (PARTITION BY trunc(s.Timestamp,'MONTH') 
                 ORDER BY s.Sales DESC) as monthly_rank
  FROM Sales s
) t
WHERE monthly_rank <= 5
  AND t.month_start BETWEEN add_months(sysdate, -1)
                        AND add_months(sysdate, -5)
GROUP BY t.Brand;

4) Last thing to do - LEFT JOIN query 2 and 3

SQLFiddle here http://sqlfiddle.com/#!4/46770/65

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM