Oracle SQL, IF statements - sql

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

Related

Using Max(boolean) in a case statement

I am made a temp table of accounts in a database with booleans that provide insight about the accounts. Some customers have multiple accounts so I am grouping them together and was trying to look at the MAX(Boolean) to set a status field.
My query kinda looks like:
with t as (Select lngCustomerNumber,
Case
When 'Criteria for being Active' Then 1
End as blnActive,
Case
When 'Criteria for unexpired' Then 1
End as blnUnexpired
From AccountTable)
Select t.CustomerNumber,
Case
When Max(t.blnActive) = 1
AND Max(t.blnUnexpired) = 1 Then 'Active/Unexpired'
When Max(t.blnActive) = 1
AND Max(t.blnUnexpired) = 0 Then 'Active/Expired'
When Max(t.blnActive) = 0
AND Max(t.blnUnexpired) = 1 Then 'Inactive/Unexpired'
When Max(t.blnActive) = 0
AND Max(t.blnUnexpired) = 0 Then 'Inactive/Expired'
End As strLicenseStatus
From T
Group By t.CustomerNumber
Anything where it checks if the Max(Boolean) = 1 will calc to True correctly, but if I do Max(Boolean) = 0 or Max(Boolean) <> 1 then it does not calc to True when it should.
I have tested by just looking at the grouped Temp Table with each boolean bringing back its Max() value and the ones that should be 0 are coming back as 0.
As a workaround, I have tried
Where t.CustomerNumber NOT IN (SELECT t2.CustomerNumber
FROM t t2
WHERE t2.blnUnexpired = 1
AND t2.CustomerNumber = t.CustomerNumber )
And that does give me the results that I am looking for but I have millions of rows coming back so it has been timing out after many hours, where the previous method was able to run in less than an hour.
I have some other data in my query, the one presented is a much smaller version used to highlight my issue.
Any recommendations on how I can make this work?
Thank you.
When you are defining your blnActive and blnUnexpired cases, you only have the "1" case defined, which means if it doesn't meet these criteria, it will be null. Try adding else 0 to each case:
with t as (Select lngCustomerNumber,
Case
When 'Criteria for being Active' Then 1
Else 0
End as blnActive,
Case
When 'Criteria for unexpired' Then 1
Else 0
End as blnUnexpired
From AccountTable)

WHERE conditions being listed in a column if they are met

I have a file that i receive each morning which contains details of customers whos information doesnt meet certain criteria, i have built a script with many WHERE conditions that, if met, will show customers information and put them in a file but im having trouble finding out why they are wrong.
As i have many conditions in the where clause, is there a way to show which column has the incorrect information
For example i could have a table like this:
NAME|ADDRESS |PHONE|COUNTRY
John|123avenue |12345|UK
My conditions could be
SELECT * FROM CUSTOMERS
WHERE NAME LIKE 'J%'
AND LEFT(PHONE,1) = '1'
so it would show in the file as two conditions are met, but as i have over 80 rows and 40 conditions, its hard to look at each row and find out why its in their.
Is there a way i can add a column which will tell me which WHERE condition has been met?
As worded, no. You should reverse your logic. Add fields that show what's wrong, then use those fields in a WHERE clause.
SELECT
*,
CASE WHEN LEFT(phone, 1) = '1' THEN 1 ELSE 0 END AS phone_starts_with_1,
CASE WHEN LEFT(name, 1) = 'Z' THEN 1 ELSE 0 END AS name_starts_with_z
FROM
customers
WHERE
phone_starts_with_1 = 1
OR name_starts_with_z = 1
Depending on which dialect of SQL you use, you may need to nest this, such that the new fields are resolved before you can use them in the WHERE clause...
SELECT
*
FROM
(
SELECT
*,
CASE WHEN LEFT(phone, 1) = '1' THEN 1 ELSE 0 END AS phone_starts_with_1,
CASE WHEN LEFT(name, 1) = 'Z' THEN 1 ELSE 0 END AS name_starts_with_z
FROM
customers
)
checks
WHERE
phone_starts_with_1 = 1
OR name_starts_with_z = 1

Combining CASE Statements in 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.

Remove query results with having

I have an SQL query like the following:
select aaa,
count(condition_1),
count(condition_2),
count(condition_3)
from DB
where ...
group by 1,
order by 1
The above will return four columns. Is it possible with a having statement to suppress some of the fields in the results but return all the rows that the original script would produce.
Thanks in advance for your help
if you are trying to "suppress" field values (and i assume that you're really looking to return 0 in that case, since the fields aren't going away as long as they're in the select) based on some criteria but return all rows, you could try the following:
select aaa,
case when count(condition_1) > 1 then count(condition_1) else 0 end as count_1,
case when count(condition_2) > 1 then count(condition_2) else 0 end as count_2,
case when count(condition_3) > 1 then count(condition_3) else 0 end as count_3
from DB
where ...
group by 1,
order by 1
obviously modify the case statements to reflect the values you wish to return, with all others being 0
I am not exactly sure what you mean but, from my understanding you are trying to group your results based on a single column's count. If that's right, then the code you need would be along the lines of
select aaa,
count(condition_1) as count_1,
count(condition_2) as count_2,
count(condition_3) as count_3
from DB
where ...
group by 1,
order by 1
having count_1 > 1
No, you can't suppress columns (fields) and keep all the rows.
Any filtering (WHERE, HAVING etc) will apply only to rows.
You could do this
select
aaa,
case
when somecondition then count(condition_1)
when somecondition then count(condition_2)
end as thecount,
case
when somecondition then '1'
when somecondition then '2'
end as thecountofwhat
from mytable
where ...
group by aaa,
order by aaa
Note: don't use ordinals in GROUP BY or ORDER BY. Bad practice. And only MySQL allows such nonsense in the GROUP BY.

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")