SQL aggregate rows with same id , specific value in secondary column

2.1k views Asked by At

I'm looking to filter out rows in the database (PostgreSQL) if one of the values in the status column occurs. The idea is to sum the amount column if the unique reference only has a status equals to 1. The query should not SELECT the reference at all if it has also a status of 2 or any other status for that matter. status refers to the state of the transaction.

Current data table:

reference | amount | status
   1         100       1       
   2         120       1
   2        -120       2
   3         200       1
   3        -200       2
   4         450       1

Result:

amount | status
  550      1

I've simplified the data example but I think it gives a good idea of what I'm looking for. I'm unsuccessful in selecting only references that only have status 1. I've tried sub-queries, using the HAVING clause and other methods without success.

Thanks

4

There are 4 answers

0
FuzzyTree On BEST ANSWER

Here's a way using not exists to sum all rows where the status is 1 and other rows with the same reference and a non 1 status do not exist.

select sum(amount) from mytable t1
where status = 1
and not exists (
    select 1 from mytable t2
    where t2.reference = t1.reference
    and t2.status <> 1
)
0
Damiano On
SELECT SUM(amount)
 FROM table
WHERE reference NOT IN (
 SELECT reference
 FROM table
 WHERE status<>1
)

The subquery SELECTs all references that must be excluded, then the main query sums everything except them

2
Clodoaldo Neto On
select sum (amount) as amount
from (
    select sum(amount) as amount
    from t
    group by reference
    having not bool_or(status <> 1)
) s;
 amount 
--------
    550
0
Lukasz Szozda On

You could use windowed functions to count occurences of status different than 1 per each group:

SELECT SUM(amount) AS amount
FROM (SELECT *,COUNT(*) FILTER(WHERE status<>1) OVER(PARTITION BY reference) cnt
      FROM tc) AS sub
WHERE cnt = 0;

Rextester Demo