Using CASE or NVL - sql

i would like to change code below by using SUM(NVL). any suggestion.
sum(CASE WHEN D.CURRENCY ='MYR' OR D.CURRENCY IS NULL THEN 1 ELSE 0 END) as Cur
previously i create this, but i cannot sum the 'CURRENCY' column which is 'MYR'. this column have null value.
NVL(D.CURRENCY,'MYR') CUR4
the red one i bold must display 'MYR'

First you have sum() function which actually counting the no of MYR in CURRENCY column rather than doing the sum
So, you just filter the NULLs by either COALESCE() or NVL()
SUM(CASE WHEN COALESCE(D.CURRENCY,'MYR') = 'MYR' THEN 1 ELSE 0 END) CUR4

Related

Oracle SQL: Using COUNT() >1 When Combining two CASE WHEN Statements

I have a line of SQL which produces a count of purchases variable
count(distinct case when t.transaction_sub_type =1 then t.transaction_date end) as COUNTPUR,
I need to modify this so I can produce a 0/1 flag variable, which flags if a customer is a repeat purchaser. So, when a customer's purchases are greater than 1 then flag as 1 else flag as 0.
case when COUNTPUR>1 then 1 else 0 end as FLAG_REPEATPURCHASER
I need to combine these two case statements into one. I have been experimenting with different versions of the syntax, but I can't seem to nail it down. Below is one of the experiments which do not work.
max(case when (count(distinct case when t.transaction_sub_type =1 then t.transaction_date end))>1 then 1 else 0 end) as FLAG_REPEATPURCHASER,
Thanks in advance for assitance
You can use a case expression with conditional aggregation:
(case when count(distinct case when t.transaction_sub_type = 1 then t.transaction_date end) > 1
then 1 else 0
end) as FLAG_REPEATPURCHASER

Applying ISNULL inside of a CASE expression

I need to have a way to apply ISNULL in a CASE expression that will replace the NULL values with 0. The below code runs but still returns NULL values. Is there any way to accomplish this? There are two stock types - 'A' and blank, I am trying to get the sum of the quantity for each type.
I've tried using ISNULL inside the CASE
CASE WHEN MRP.stock_type = 'A'
THEN ISNULL(SUM(MRP.QUANTITY),0)
END AS 'Uncovered_Quantity',
CASE WHEN MRP.stock_type = ' '
THEN ISNULL(SUM(MRP.QUANTITY),0)
END AS 'Blank_Quantity',
I think you probably intended conditional aggregation:
SUM(CASE WHEN MRP.stock_type = 'A' THEN MRP.QUANTITY ELSE 0 END) as Uncovered_Quantity,
SUM(CASE WHEN MRP.stock_type = ' ' THEN MRP.QUANTITY ELSE 0 END) as Blank_Quantity,

Replacing NULL with 0 in a SQL server query

I have developed a query, and in the results for the first three columns I get NULL. How can I replace it with 0?
Select c.rundate,
sum(case when c.runstatus = 'Succeeded' then 1 end) as Succeeded,
sum(case when c.runstatus = 'Failed' then 1 end) as Failed,
sum(case when c.runstatus = 'Cancelled' then 1 end) as Cancelled,
count(*) as Totalrun from
( Select a.name,case when b.run_status=0 Then 'Failed' when b.run_status=1 Then 'Succeeded'
when b.run_status=2 Then 'Retry' Else 'Cancelled' End as Runstatus,
---cast(run_date as datetime)
cast(substring(convert(varchar(8),run_date),1,4)+'/'+substring(convert(varchar(8),run_date),5,2)+'/' +substring(convert(varchar(8),run_date),7,2) as Datetime) as RunDate
from msdb.dbo.sysjobs as a(nolock) inner join msdb.dbo.sysjobhistory as b(nolock)
on a.job_id=b.job_id
where a.name='AI'
and b.step_id=0) as c
group by
c.rundate
When you want to replace a possibly null column with something else, use IsNull.
SELECT ISNULL(myColumn, 0 ) FROM myTable
This will put a 0 in myColumn if it is null in the first place.
You can use both of these methods but there are differences:
SELECT ISNULL(col1, 0 ) FROM table1
SELECT COALESCE(col1, 0 ) FROM table1
Comparing COALESCE() and ISNULL():
The ISNULL function and the COALESCE expression have a similar
purpose but can behave differently.
Because ISNULL is a function, it is evaluated only once. As
described above, the input values for the COALESCE expression can be
evaluated multiple times.
Data type determination of the resulting expression is different.
ISNULL uses the data type of the first parameter, COALESCE follows
the CASE expression rules and returns the data type of value with
the highest precedence.
The NULLability of the result expression is different for ISNULL and
COALESCE. The ISNULL return value is always considered NOT NULLable
(assuming the return value is a non-nullable one) whereas COALESCE
with non-null parameters is considered to be NULL. So the
expressions ISNULL(NULL, 1) and COALESCE(NULL, 1) although
equivalent have different nullability values. This makes a
difference if you are using these expressions in computed columns,
creating key constraints or making the return value of a scalar UDF
deterministic so that it can be indexed as shown in the following
example.
-- This statement fails because the PRIMARY KEY cannot accept NULL values
-- and the nullability of the COALESCE expression for col2
-- evaluates to NULL.
CREATE TABLE #Demo
(
col1 integer NULL,
col2 AS COALESCE(col1, 0) PRIMARY KEY,
col3 AS ISNULL(col1, 0)
);
-- This statement succeeds because the nullability of the
-- ISNULL function evaluates AS NOT NULL.
CREATE TABLE #Demo
(
col1 integer NULL,
col2 AS COALESCE(col1, 0),
col3 AS ISNULL(col1, 0) PRIMARY KEY
);
Validations for ISNULL and COALESCE are also different. For example,
a NULL value for ISNULL is converted to int whereas for COALESCE,
you must provide a data type.
ISNULL takes only 2 parameters whereas COALESCE takes a variable
number of parameters.
if you need to know more here is the full document from msdn.
With coalesce:
coalesce(column_name,0)
Although, where summing when condition then 1, you could just as easily change sum to count - eg:
count(case when c.runstatus = 'Succeeded' then 1 end) as Succeeded,
(Count(null) returns 0, while sum(null) returns null.)
When you say the first three columns, do you mean your SUM columns? If so, add ELSE 0 to your CASE statements. The SUM of a NULL value is NULL.
sum(case when c.runstatus = 'Succeeded' then 1 else 0 end) as Succeeded,
sum(case when c.runstatus = 'Failed' then 1 else 0 end) as Failed,
sum(case when c.runstatus = 'Cancelled' then 1 else 0 end) as Cancelled,
SQL Fiddle Demo
A Simple way is
UPDATE tbl_name SET fild_name = value WHERE fild_name IS NULL
If you are using Presto, AWS Athena etc, there is no ISNULL() function. Instead, use:
SELECT COALESCE(myColumn, 0 ) FROM myTable
Wrap your column in this code.
ISNULL(Yourcolumn, 0)
Maybe check why you are getting nulls
Use COALESCE, which returns the first not-null value e.g.
SELECT COALESCE(sum(case when c.runstatus = 'Succeeded' then 1 end), 0) as Succeeded
Will set Succeeded as 0 if it is returned as NULL.
Add an else to your case statements so that they default to zero if the test condition is not found. At the moment if the test condition isn't found NULL is being passed to the SUM() function.
Select c.rundate,
sum(case when c.runstatus = 'Succeeded' then 1 else 0 end) as Succeeded,
sum(case when c.runstatus = 'Failed' then 1 else 0 end) as Failed,
sum(case when c.runstatus = 'Cancelled' then 1 else 0 end) as Cancelled,
count(*) as Totalrun from
( Select a.name,case when b.run_status=0 Then 'Failed' when b.run_status=1 Then 'Succeeded'
when b.run_status=2 Then 'Retry' Else 'Cancelled' End as Runstatus,
---cast(run_date as datetime)
cast(substring(convert(varchar(8),run_date),1,4)+'/'+substring(convert(varchar(8),run_date),5,2)+'/' +substring(convert(varchar(8),run_date),7,2) as Datetime) as RunDate
from msdb.dbo.sysjobs as a(nolock) inner join msdb.dbo.sysjobhistory as b(nolock)
on a.job_id=b.job_id
where a.name='AI'
and b.step_id=0) as c
group by
c.rundate
sum(case when c.runstatus = 'Succeeded' then 1 else 0 end) as Succeeded,
sum(case when c.runstatus = 'Failed' then 1 else 0 end) as Failed,
sum(case when c.runstatus = 'Cancelled' then 1 else 0 end) as Cancelled,
the issue here is that without the else statement, you are bound to receive a Null when the run status isn't the stated status in the column description. Adding anything to Null will result in Null, and that is the issue with this query.
Good Luck!
by following previous answers I was losing my column name in SQL server db however following this syntax helped me to retain the ColumnName as well
ISNULL(MyColumnName, 0) MyColumnName
For regular SQL, ISNULL(item) can only take one parameter, and thus 90% of these solutions don't work.
I repurposed #Krishna Chavali's answer to make this:
(CASE WHEN (NOT ISNULL(column_name)) THEN column_name ELSE 0 END) AS ColumnName
This will return the value in column_name if it is not null, and 0 if it is null.
UPDATE TableName SET ColumnName= ISNULL(ColumnName, 0 ) WHERE Id = 10

How to count the rows which contains non zero values in sql

SELECT round(COUNT(dmd_1wk),2) AS NBR_ITEMS_1WK
FROM table;
Field dmd_1wk has so many zeros in it. How do I Count the non zero values?
It sounds like you just need to add a WHERE clause:
SELECT
round(COUNT(dmd_1wk),2) AS NBR_ITEMS_1WK
FROM table
WHERE dmd_1wk <> 0;
If you want the count of both non-zero and zero values, then you can use something like:
SELECT
round(COUNT(case when dmd_1wk <> 0 then dmd_1wk end),2) AS NBR_ITEMS_1WK_NonZero,
round(COUNT(case when dmd_1wk = 0 then dmd_1wk end),2) AS NBR_ITEMS_1WK_Zero
FROM table;
Method 1: Case Statement. This may be useful if you need to continue to process all rows (which a where clause would prevent).
SELECT count(case when dmd_1wk = 0 then 0 else 1 end) as NonZeroCount FROM MyTable
Method 2: Where Clause.
SELECT
count(1) as NonZeroCount
FROM
MyTable
WHERE
dmd_1wk <> 0
I'd like to offer another solution using NULLIF since COUNT won't count NULL values:
SELECT round(COUNT(NULLIF(dmd_1wk,0)),2) AS NBR_ITEMS_1WK
FROM table;
And here is the Fiddle.
Good luck.
Methinks bluefeets answer is probably what you are really looking for, as it sounds like you just want to count non-zeros; but this will get you a count of zero and non-zero items if that's not the case:
SELECT
ROUND(SUM(CASE NVL(dmd_1wk, 0) = 0 THEN 1 ELSE 0 END), 2) AS "Zeros",
ROUND(SUM(CASE NVL(dmd_1wk, 0) != 0 THEN 1 ELSE 0 END), 2) AS "NonZeros"
FROM table
Although there is no point in rounding a whole number, I've included your original ROUNDs as I'm guessing you're using it for formatting, but you might want to use:
TO_CHAR(SUM(...), '999.00')
as that's the intended function for formatting numbers.
You can filter them.
SELECT round(COUNT(dmd_1wk),2) AS NBR_ITEMS_1WK
FROM table
WHERE dmd_1wk <> 0;

How to COUNT column values differently in a VIEW?

I have a column in Datablase Table, Suppose its Observation which contains three types of values
Positive
Negative
NULL
Now I want to count the Total no of rows , Total Positive and Total Negative and some other columns. I can not use Where clause here. And its a view
So result should be like
Total Positive Negative SomeOtherCoulumn
255 80 120 Test1
315 135 65 Test2
I tried to use SQL COUNT here but could not get the desired results.
SELECT
COUNT(*) AS Total,
SUM(CASE WHEN Observation = 'Positive' THEN 1 ELSE 0 END) AS Positive,
SUM(CASE WHEN Observation = 'Negative' THEN 1 ELSE 0 END) AS Negative,
SomeOtherColumn
FROM your_view
GROUP BY SomeOtherColumn
There's an interesting technique of summing a case expression like so:
sum(case when Observation = 'Positive' then 1 else 0 end) 'TotalPositive'
The rest is easy.