Aakriti Choube
asked on
How to use Sum-If Type function in SQL?
Hi. I want to add some values in SQL on the basis of some other condition(something like using sum-if in excel). Below is the example:
I have a table with three columns using which I want to calculate the total product value and store the value in a column with respect to Bound Status and keeping values for other statuses as Zero.
Input Table:
Product Status Value
ABC-01 Bound 10
ABC-02 End 12
ABC-03 Canc -2
DEF-01 Bound 15
EFG-01 Bound 20
EFG-02 Canc -15
Output Table:
Product Status Value Final Value
ABC-01 Bound 10 20
ABC-02 End 12 0
ABC-03 Canc -2 0
DEF-01 Bound 15 15
EFG-01 Bound 20 5
EFG-02 Canc -15 0
Thanks
I have a table with three columns using which I want to calculate the total product value and store the value in a column with respect to Bound Status and keeping values for other statuses as Zero.
Input Table:
Product Status Value
ABC-01 Bound 10
ABC-02 End 12
ABC-03 Canc -2
DEF-01 Bound 15
EFG-01 Bound 20
EFG-02 Canc -15
Output Table:
Product Status Value Final Value
ABC-01 Bound 10 20
ABC-02 End 12 0
ABC-03 Canc -2 0
DEF-01 Bound 15 15
EFG-01 Bound 20 5
EFG-02 Canc -15 0
Thanks
I don't understand how you get to the final value but a sum-if in SQL would be something like this:
select product, status, sum(case status when 'bound' the value else 0 end) as TotalValue from yourtablename group by product, status
by your title i would use a case inside a sum
but the input and output suggest a different approach
sample
but the input and output suggest a different approach
with cte as (select substr(product, 1, 3) prod, sum(value) fv from input_table group by substr(product, 1, 3) )
select a.product, a.status, a.value, nvl(b.fv, 0) final_value
from input_table a
left join cte b on (substr(a.product, 1, 3) = b.prod and a.status = 'BOUND')
sample
or combine it ... this might give performance problems
select a.product, a.status, a.value,
case when status = 'Bound' then (
select sum(value) from input_table b
where substr(a.product, 1, 3) = substr(b.product, 1, 3) ) else 0 end final_value
from input_table a
whats the logic for "Final Value" in your sample data?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks Chris. It worked. But I have a doubt regarding 'Over' and 'Partition by'. What is the use of it and when should we use it? As I was using the similar queries except the last part..:)
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
you'll probably get better performance if you split the product column into a base name and a number
unless you add a function index on the expression substr(product, 1, 3)
unless you add a function index on the expression substr(product, 1, 3)
another approach using CTE and using the logic by Chris
* remove line 2-11 and modify table name accordingly to use in your db
with
MyTable as (
select * from (
VALUES
('ABC-01', 'Bound', 10 ),
('ABC-02', 'End', 12 ),
('ABC-03', 'Canc', -2 ),
('DEF-01', 'Bound', 15 ),
('EFG-01', 'Bound', 20 ),
('EFG-02', 'Canc', -15 )
) as myTable(Product, Status, Value)),
t as (select left(Product, CharIndex('-', Product)-1) PrdCtg, * from MyTable)
SELECT *,
CASE WHEN T.Status = 'Bound'
THEN SUM(T.Value) OVER (PARTITION BY PrdCtg)
ELSE 0
END FinalValue
FROM t
ORDER BY PrdCtg, Product;
PrdCtg Product Status Value FinalValue
ABC ABC-01 Bound 10 20
ABC ABC-02 End 12 0
ABC ABC-03 Canc -2 0
DEF DEF-01 Bound 15 15
EFG EFG-01 Bound 20 5
EFG EFG-02 Canc -15 0
* remove line 2-11 and modify table name accordingly to use in your db
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks Chris.
any further assistance is required here?
what's the issue with solution here ID: 42259059
it is giving the result that you ask for...
it is giving the result that you ask for...
the solution proposed @ ID: 42259059 should be included in assited/accepted list...
accepting your own comments and your friends ?
and ignoring the rest ?
in search of poinx or something ?
and ignoring the rest ?
in search of poinx or something ?
can't really get the logic, can you elaborate further?