Skip to Main Content

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, david.

Asked: August 12, 2016 - 8:02 pm UTC

Last updated: August 15, 2016 - 12:00 pm UTC

Version: 10.2

Viewed 1000+ times

You Asked

greetings experts, I haven't seen this matter among other questions, certainly won't mind having it pointed out if I've missed it.

I have an awkward requirement from management that requires summing a set of values, and each value is often going to be a repeated amount within a set of records, and I need to accumulate only one occurrence. I need to sum at the cat level the unique (among cat+cid) unit_max values, other values on the table records are GROUP BY factors or other aggregated values, can't be discarded. The awkward requirement has already placed the value for unit_max on each record, and it is the maximum of the unit value for all the records within the subgroup cat+cid.

CREATE TABLE category_test
(
    cat             VARCHAR2(1),
    cid             NUMBER(3),
    unit            NUMBER(4),
    unit_max        NUMBER(4)
);


INSERT INTO category_test values ('A' cat,111 cid,30 unit,45 unit_max FROM dual);
INSERT INTO category_test (SELECT 'A' cat,111 cid,30 unit,45 unit_max FROM dual);
INSERT INTO category_test (SELECT 'A' cat,111 cid,45 unit,45 unit_max FROM dual);

INSERT INTO category_test (SELECT 'B' cat,111 cid,30 unit,50 unit_max FROM dual);
INSERT INTO category_test (SELECT 'B' cat,111 cid,50 unit,50 unit_max FROM dual);
INSERT INTO category_test (SELECT 'B' cat,111 cid,20 unit,50 unit_max FROM dual);
INSERT INTO category_test (SELECT 'B' cat,222 cid,20 unit,20 unit_max FROM dual);

INSERT INTO category_test (SELECT 'C' cat,111 cid,45 unit,45 unit_max FROM dual);
INSERT INTO category_test (SELECT 'C' cat,222 cid,45 unit,45 unit_max FROM dual);
COMMIT;



This code is a beginning on what I need, but clearly not achieving the desired result for the outcome on unit_max:

SELECT  cat,
        sum(unit) new_unit,
        sum(UNIQUE unit_max) new_max 
FROM    category_test
GROUP BY cat;


GETTING:

C        NEW_UNIT         NEW_MAX
- --------------- ---------------
A             105              45
B             120              70
C              90              45


NEED HELP TO GET:
                    -- second value determination:
A     105     45    -- 'A'+111 -> 45
B     120     70    -- 'B'+111 -> 50, 'C'+222 -> 20
C      90     90    -- 'B'+111 -> 45, 'C'+222 -> 45

and Connor said...

We can use an analytic to null out the unit_max values we dont want, and then sum

SQL> select c.*,
  2         case when row_number() over ( partition by cat, cid order by rowid ) = 1
  3           then unit_max end as new_unit_max
  4  from   category_test c;

C        CID       UNIT   UNIT_MAX NEW_UNIT_MAX
- ---------- ---------- ---------- ------------
A        111         30         45           45
A        111         30         45
A        111         45         45
B        111         30         50           50
B        111         50         50
B        111         20         50
B        222         20         20           20
C        111         45         45           45
C        222         45         45           45

9 rows selected.

SQL> SELECT  cat,
  2          sum(unit) new_unit,
  3          sum(new_unit_max) new_max
  4  FROM
  5  (
  6  select c.*,
  7         case when row_number() over ( partition by cat, cid order by rowid ) = 1
  8           then unit_max end as new_unit_max
  9  from   category_test c
 10  )
 11  GROUP BY cat;

C   NEW_UNIT    NEW_MAX
- ---------- ----------
A        105         45
B        120         70
C         90         90

3 rows selected.


Rating

  (1 rating)

Is this answer out of date? If it is, please let us know via a Comment

Comments

use of analytics to solve an unusual requirement

david s., August 15, 2016 - 9:46 am UTC

a mos excellent reply, those analytic functions turn out to be very powerful. thanks for a prompt and useful reply, even though my test setup code wasn't perfect!
Connor McDonald
August 15, 2016 - 12:00 pm UTC

You *had* a test case...that puts you WAY WAY WAY ahead of the game.

I've got a whole (30) video series on analytics you might find useful

https://www.youtube.com/watch?v=xvZ4SmKtazs

More to Explore

Analytics

Analytic SQL got you confused? Check out Connor McDonald's complete video course.