Combining CASE Statements in SQL - sql

What I am trying to do is combine (2) CASE statements that each return a SUM and then take the SUM of those results. Here's what I have so far:
COUNT((
CASE (COUNT(table.CODE))
WHEN 0
THEN 0
ELSE SUM(
CASE table.CODE
WHEN '100'
THEN 1
ELSE 0
END)) (
CASE (COUNT(table.CODE))
WHEN 0
THEN 0
ELSE (SUM(
CASE table.CODE
WHEN '50'
THEN 1
ELSE 0
END))))
|| AS Total Code
I think I'm over-complicating this. The error I am receiving is Missing Keyword (at the beginning of the 2nd CASE statement). Any thoughts?

When you have an overload of parentheticals, you might find it helpful to go overboard with indention to spot problems:
COUNT
(
(
CASE (COUNT(table.CODE))
WHEN 0
THEN 0
ELSE SUM
(
CASE table.CODE
WHEN '100'
THEN 1
ELSE 0
END
)
<--Should be an END here?-->
) <--What is happening here-->
(
CASE (COUNT(table.CODE))
WHEN 0
THEN 0
ELSE
(
SUM
(
CASE table.CODE
WHEN '50'
THEN 1
ELSE 0
END
)
)
<--Should be an END here?-->
)
)
|| AS Total Code
You can see that there are two CASE statements butted up against each other with no operator to make any sense of it.
You might also spot that your first and third CASE are not closed with an END, which is what MySQL is balking about.
Lastly, that double-bar in MySQL is an "OR" operator. But you are not OR'ing anything... Not sure what the plan was here.
Ultimately, though, I think you are going to run into problems Counting a Sum in the same query. You may have to move those SUM(CASE...END) bits into a subquery and then doing the COUNT outside of that.

After looking over the answers to my questions, this is what I came up with:
CASE (COUNT(table.CODE))
WHEN 0
THEN 0
ELSE ((SUM(
CASE table.CODE
WHEN '100'
THEN 1
WHEN '50'
THEN 1
ELSE 0
END))
END) AS Value5
I'm cleaning up old code so I didn't completely understand what I was looking at because its all over the place. This is a lot cleaner and I'm positive that I am getting desired response now.

Related

Error: Cannot perform an aggregate function SQL

1.) I am getting an error for using SUM function in SQL is there a possible way to fix this, I tried searching the internet, but most of the examples are for single column.
SELECT
r.WorkOrderBatch,
wo.ProductCode,
wo.WorkOrderQty,
Convert(DATE,wo.StartDate),
wo.CurrentStatus,
replace this line:
SUM(COUNT(CASE r.IsTestPass WHEN 1 THEN NULL ELSE 1 END)) AS FailedQty
With
SUM(CASE r.IsTestPass WHEN 1 THEN 0 ELSE 1 END) AS FailedQty
rest everything looks good

Oracle SQL, IF statements

I’m running a query from a table that has info on account numbers, settled charges , the write off figure, and the reason for the write off; so the table is called group_write_off and the table headings, account_id, charge_settled_date, total_charge_amount, amount_written_off, write_off_reason. What I want to do, is pull everything through, so
Select * from
group_write_off
but for any case where the write_off_reason includes the word ‘Audit’, I want amount_written_off to show as 0 (zero), for all others i want the original amount_written_off to show.
Many thanks.
Use CASE expression.
SELECT CASE WHEN write_off_reason='Audit' THEN 0 ELSE amount_written_off END
FROM group_write_off
Also try below for checking if Audit word is present in column write_off_reason by using INSTR() function
SELECT CASE WHEN INSTR(write_off_reason,'Audit') = 0 THEN 0 ELSE amount_written_off END
FROM group_write_off
If you want more words
SELECT CASE WHEN INSTR(write_off_reason,'Audit') = 0 THEN 0
WHEN INSTR(write_off_reason,'admin') = 0 THEN 0
ELSE amount_written_off END
FROM group_write_off

How do I find the percentage between two columns in postgresql?

Two parameters in my SELECT statement are:
count(product_code.code) as codes_allocated
count(case when product_code.taken='TRUE' then product_code.taken end) as codes_claimed
I would like to add one more parameter to my select statement that takes the codes_claimed and divides it by the codes_allocated to get a percentage of the codes claimed.
I've tried many things but always get the error:
ERROR: division by zero
Query failed.
My most recent attempt used the following:
(count(case when core_isvcode.reserved='TRUE' then core_isvcode.reserved end)::decimal / count(core_isvcode.code)::decimal)*100 as Percent_redeemed`
Any help and guidance is greatly appreciated!
why not include a CASE to validate count(core_isvcode.code) > 0
CASE WHEN count(core_isvcode.code) > 0 THEN
(count(case when core_isvcode.reserved='TRUE' then core_isvcode.reserved end)::decimal
/ count(core_isvcode.code)::decimal)*100
ELSE NULL
END as Percent_redeemed
I think nullif() is often the simplest method:
(count(case when core_isvcode.reserved='TRUE' then core_isvcode.reserved end)::decimal / nullif(count(core_isvcode.code)::decimal))*100 as Percent_redeemed
However, I think avg() is simpler for this calculation:
avg(case when core_isvcode.reserved = 'TRUE' then 100.0
when core_isvcode.reserved is null then NULL
else 0.0
end)

Multiple columns within a single CASE statement

I'm sure this has be covered many times so please pardon my repeat. I have a query that works but currently has 6 CASE statements within one select. Someone mentioned that it would be best optimized by putting all my WHEN conditions within a single CASE. However, I'm unable to achieve this
select right(RTRIM(region),5) as cell_id,
sum(CASE WHEN LEFT(cparty,3) in ('999','998','997') THEN chargeduration/60 else 0 END) AS OnNet_Minutes,
sum(CASE WHEN LEFT(cparty,3) in ('996','995') THEN chargeduration/60 else 0 END) AS OffNet_C_Minutes,
sum(CASE WHEN LEFT(cparty,3) in ('994','993','992') THEN chargeduration/60 else 0 END) AS OffNet_A_Minutes,
sum(CASE WHEN LEFT(cparty,3) in ('991','990') THEN chargeduration/60 else 0 END) AS OffNet_S_Minutes,
sum(CASE WHEN LEFT(cparty,2) = '00' THEN chargeduration/60 else 0 END) AS OffNet_T_Minutes,
sum(CASE WHEN len(cparty) < 6 and LEFT(cparty,1) <> 0 THEN chargeduration/60 else 0 END) AS SC_Minutes
from August.dbo.cdr20130818
where CHARGEDURATION > 0 and ISNULL(region,'''')<>'''' and LEN(region) > 5
group by right(RTRIM(region),5)
order by right(RTRIM(region),5) asc
In your case, you can't put them all into one CASE, since the results all go into different columns of the select.
BTW, you should remove your ISNULL(region, '''') <> '''' condition, as it's redundant when paired with the LEN(region) > 5 condition. (When region is null, then LEN(region) is also null, and NULL > 5 is false.)
I think you have it right, six different SUM()'s that each have meaning on their own.
If all of your criteria were in the same CASE statement you'd lose detail, you'd be returning the SUM() of your currently separate statements combined into one.
Combining redundant criteria in the WHERE clause can clean up a CASE statement, but you don't have anything completely redundant here.

SQL COUNT specific unit IF another field <> 0

I have a query that has a select statement that contains the following:
,COUNT(u.[Unit])
,up.[Number_Of_Stops]
I need to only count the units where number of stops <> 0. This has more details in the query so I can't just say WHERE number_of_stops <> 0. It has to be within the select statement.
Thanks
Try:
SUM(CASE WHEN up.[Number_Of_Stops] != 0 THEN 1 ELSE 0 END) AS countWhereNumStopsNotZero
(Edit: original answer said "COUNT" not "SUM")