Question

I have 2 progress database queries and I'm trying to merge them into one statement, but I am getting errors. Each of these queries simply returns a number and I would like to sum those 2 numbers together. Either that or make another query from scratch. They both take in a set of value codes for "DM1" and they both accept 1 "product".

Query 1

SELECT SUM(opn3.samt)
    FROM PUB.ord ord3, PUB.opn opn3
    WHERE
    ord3.subsnum = opn3.subsnum
    AND ord3.onum = opn3.onum
    AND ord3.DM1 != ''
    AND ord3.DM1 IN('XCWAJC25','WCWAMO73') 
    AND ord3.prdcde = 'CSC' 
    AND ord3.stat != 16
    AND opn3.samt >= 0
    GROUP BY ord3.DM1, ord3.prdcde

Query 2

SELECT SUM((-1 * opn2.samt) + ord2.samt)
    FROM PUB.ord ord2, PUB.opn opn2
    WHERE
    ord2.subsnum = opn2.subsnum
    AND ord2.onum = opn2.onum
    AND ord2.DM1 != ''
    AND ord2.DM1 IN('XCWAJC25','WCWAMO73') 
    AND ord2.prdcde = 'CSC' 
    AND ord2.stat = 16
    AND opn2.samt < 0
    GROUP BY ord2.DM1, ord2.prdcde

Merge attempt so far...

SELECT SUM(opn3.samt + (SELECT SUM((-1 * opn2.samt) + ord2.samt)
    FROM PUB.ord ord2, PUB.opn opn2
    WHERE
    ord2.subsnum = opn2.subsnum
    AND ord2.onum = opn2.onum
    AND ord2.DM1 != ''
    AND ord2.DM1 = ord3.DM1
    AND ord2.prdcde = ord3.prdcde 
    AND ord2.stat = 16
    AND opn2.samt < 0
    GROUP BY ord2.DM1, ord2.prdcde
)) as foo

    FROM PUB.ord ord3, PUB.opn opn3
    WHERE
    ord3.subsnum = opn3.subsnum
    AND ord3.onum = opn3.onum
    AND ord3.DM1 != ''
    AND ord3.DM1 IN('XCWAJC25','WCWAMO73') 
    AND ord3.prdcde = 'CSC' 
    AND ord3.stat != 16
    AND opn3.samt >= 0
    GROUP BY ord3.DM1, ord3.prdcde

Thanks

Was it helpful?

Solution

I think this will work, although it would be nice to have sample data to verify:

SELECT COALESCE(SUM(a.samt), 0) - COALESCE(SUM(b.samt), 0)
       + COALESCE(SUM(CASE WHEN ord.stat = 16
                                AND b.samt < 0
                           THEN ord.samt END), 0)
FROM PUB.ord ord
LEFT JOIN PUB.opn a
       ON a.subsnum = ord.subsnum
          AND a.onum = ord.onum
          AND a.samt >= 0
          AND ord.stat != 16
LEFT JOIN PUB.opn b
          ON b.subsnum = ord.subsnum
             AND b.onum = ord.onum
             AND b.samt < 0
             AND ord.stat = 16
WHERE ord.DM1 IN('XCWAJC25', 'WCWAMO73') 
      AND ord.prdcde = 'CSC'
GROUP BY ord.DM1

Notes on query/stuff:

  • Always explicitly qualify joins, don't use the comma-separated FROM clause
  • I don't think you needed ord.DM1 != '', given that values have to be in a specific set
  • Putting a clause into a LEFT JOIN condition instead of the WHERE clause has a slightly different effect; it adds the condition to the join, instead of the filtering. This means that rows can be excluded based on something in the left table, regardless of whether you need the actual row (this is why ord.stat ended up in the LEFT JOINs). INNER JOINs would technically behave the same way, but it isn't usually noticeable because causing the right table to be excluded also excludes the left table.

OTHER TIPS

I think this should do the trick, given the the individual queries work as intended:

SELECT sum1.tot + sum2.tot 
FROM  
(SELECT SUM(opn3.samt) as tot
FROM PUB.ord ord3, PUB.opn opn3
WHERE
ord3.subsnum = opn3.subsnum
AND ord3.onum = opn3.onum
AND ord3.DM1 != ''
AND ord3.DM1 IN('XCWAJC25','WCWAMO73') 
AND ord3.prdcde = 'CSC' 
AND ord3.stat != 16
AND opn3.samt >= 0
GROUP BY ord3.DM1, ord3.prdcde) sum1,

(SELECT SUM((-1 * opn2.samt) + ord2.samt) as tot
FROM PUB.ord ord2, PUB.opn opn2
WHERE
ord2.subsnum = opn2.subsnum
AND ord2.onum = opn2.onum
AND ord2.DM1 != ''
AND ord2.DM1 IN('XCWAJC25','WCWAMO73') 
AND ord2.prdcde = 'CSC' 
AND ord2.stat = 16
AND opn2.samt < 0
GROUP BY ord2.DM1, ord2.prdcde) sum2
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top