Home > Software engineering >  Difference of SUM while doing multiple group by
Difference of SUM while doing multiple group by

Time:10-11

I have table like below

Pid qid count sum
11 13 5 800
12 13 7 300
11 14 3 100
12 14 5 200

I need to get the difference of sum while doing group by using pid and qid

Like

SELECT
    /* ??? */
FROM
    tbl
GROUP BY
    pid,
    qid
Id1 id2 qid difference
11 12 13 500

CodePudding user response:

Use conditional aggregation:

SELECT 11 AS id1,
       12 AS id2,
       qid,
       ABS(SUM(CASE pid WHEN 11 THEN value WHEN 12 THEN -value END)) AS diff
FROM   tbl
GROUP BY qid;

Which, for the sample data:

CREATE TABLE tbl (Pid, qid, value) AS
  SELECT 11, 13, 160 FROM DUAL CONNECT BY LEVEL <= 5 UNION ALL
  SELECT 12, 13,  43 FROM DUAL CONNECT BY LEVEL <= 6 UNION ALL
  SELECT 12, 13,  42 FROM DUAL CONNECT BY LEVEL <= 1 UNION ALL
  SELECT 11, 14,  30 FROM DUAL CONNECT BY LEVEL <= 2 UNION ALL
  SELECT 11, 14,  40 FROM DUAL CONNECT BY LEVEL <= 1 UNION ALL
  SELECT 12, 14,  40 FROM DUAL CONNECT BY LEVEL <= 5;

Outputs:

ID1 ID2 QID DIFF
11 12 13 500
11 12 14 100

fiddle

CodePudding user response:

Looks like you want a difference of sum between all pairs of different pid per each qid. The easiest and most reliable solution in this case would be to use a simple self join, like this:

with agg as (
select pid, qid
  , count(*) as cnt
  , sum(?) as sum1
from your_table
group by pid, qid
)
select
 t1.pid as id1
,t2.pid as id2
,abs(t2.sum1-t1.sum1) as diff
from agg t1
     join agg t2
       on t1.qid=t2.qid
       and t1.pid<t2.pid

Obviously, we could optimize it if we were sure that you have just 2 different PIDs per each qid, but you haven't mention it

  • Related