NULL values not filtered out with WHERE statement - sql

SELECT ID, VOLUME, TYPEOF(VOLUME) FROM DBT.BASE
When I select these columns, I see that the results have some NULL values. They don't seem to be strings. However, when I try to filter the NULL values out with a where statement:
SELECT ID, VOLUME, TYPEOF(VOLUME) FROM DBT.BASE WHERE VOLUME = NULL
I don't see any results. What might be the possible causes? I also tried filtering with 'NULL' but that would throw an error since the column type is double.

use this for only want null recode
SELECT ID, VOLUME, TYPEOF(VOLUME) FROM DBT.BASE WHERE VOLUME IS NULL
or
SELECT ID, VOLUME, TYPEOF(VOLUME) FROM DBT.BASE WHERE ISNULL(VOLUME,'') = ''
if you get not null value then use
SELECT ID, VOLUME, TYPEOF(VOLUME) FROM DBT.BASE WHERE ISNULL(VOLUME,'') <> ''
or
SELECT ID, VOLUME, TYPEOF(VOLUME) FROM DBT.BASE WHERE VOLUME IS NOT NULL

a more full answer is NULL is not directly comparable, much like NaN is not comparable in floating point numbers. Both represent the "lack of a value" if you "have not value here" how can you compare it to something.
"There is nobody next to you, what is their name?" it just doesn't make sense.
So to test you ask column IS NULL or column IS NOT NULL or you can use a compact logic expression see Conditional Expressions but some common ones in Snowflake are:
short form
ANSI long
snowflake long
NVL(column,'')
CASE WHEN column IS NOT NULL THEN column ELSE '' END
IFF(column IS NOT NULL, column, '')
NVL2(column,'a','b')
CASE WHEN column IS NOT NULL THEN 'a' ELSE 'b' END
IFF(column IS NOT NULL, 'a', 'b')
ZEROIFNULL(column)
CASE WHEN column IS NOT NULL THEN column ELSE 0 END
IFF(column IS NOT NULL, column, 0)
COALESCE/NVL/IFNULL are all interchangable so I will only show one (expect COALESCE can handle N items which are checked in order)

You can use the where is function or is not function to filter all the null values.

Related

How to use DATEADD in a case statement in snowflake?

I have a table with a column PERIOD_DAYS that is in varchar but contains a lot of numbers. I have another column called FIRST_DATETIME, which is in datetime data type. I want to add the numbers in the PERIOD_DAYS to the FIRST_DATETIME to get the FINAL datetime. So if datetime = '2020-01-01' + 2 DAYS, the final_datetime should be = '2020-01-03'
I have a query that contains a case statement, that says if the first_datetime IS NULL, then default the final_datetime to 0. However, I keep getting an error.
This works:
select
ID,
PERIOD_DAYS,
FIRST_DATETIME,
DATEADD('days',try_to_number(PERIOD_DAYS), FIRST_DATETIME) as FINAL_DATETIME
from TBL_A a
group by ID,PERIOD_DAYS,FINAL_DATETIME
Does not work:
select
ID,
PERIOD_DAYS,
FIRST_DATETIME,
case when try_to_number(PERIOD_DAYS) IS NULL then 0 else DATEADD('days',try_to_number(PERIOD_DAYS), FIRST_DATETIME) END as FINAL_DATETIME
from TBL_A a
group by ID,PERIOD_DAYS,FINAL_DATETIME
I need the second query to work to take into account the non-numeric values in period_days columns.
The problem as you have it is because you CASE is returning 0 which is a NUMBER on one branch and TIMESTAMP_NTZ on the other.
These are not compatible types. I would recommend using NULL instead of zero.
thus:
CASE WHEN try_to_number(PERIOD_DAYS) IS NULL THEN null
ELSE DATEADD('days',try_to_number(PERIOD_DAYS), FIRST_DATETIME)
END as FINAL_DATETIME
Given this only has 2 branches a IFF can be used instead:
IFF(try_to_number(PERIOD_DAYS) IS NULL, null, DATEADD('days',try_to_number(PERIOD_DAYS), FIRST_DATETIME) ) as FINAL_DATETIME

How to write case condition to check particular value exist among multiple values in sql?

I have a column in table which is having single/multiple value. I have to convert it yes/no based on condition.
example:
rendition_type_sys
distribution
uploaded, distribution
uploaded
single
I need to change the value based on condition. If column having distribution then value should convert as 'Yes' otherwise 'No'
Final Output:
rendition_type_sys
Yes
Yes
No
No
I tried one case statement but that is working for single value not multiple value-
case when ren.rendition_type__sys='distribution' then 'Yes' else 'No' end as rendition_type__sys
First, you should fix your data model so you are not storing multiple values in a string.
In the meantime, like should do what you want. For your example:
(case when ren.rendition_type__sys like '%distribution%'
then 'Yes' else 'No'
end) as rendition_type__sys
Note: In case "distribution" is part of an element name and you don't want that, you can check for delimiters. In Standard SQL, this would be:
(case when ', ' || ren.rendition_type__sys || ', ' like '%, distribution, %'
then 'Yes' else 'No'
end) as rendition_type__sys
The string concatenation operator may vary depending on the database you are using.
This below code would work assuming distribution is not part of any other discrete value; here is the code in a sample form:
WITH rt AS (
SELECT 'distribution' AS rendition_type_sys
UNION SELECT 'uploaded, distribution'
UNION SELECT 'uploaded'
UNION SELECT 'single'
)
SELECT CASE WHEN rt.rendition_type_sys LIKE 'distribution' THEN 'Yes' ELSE 'No' END AS Col
FROM rt
You might consider adding a table with for these "tags" so that they are discrete.

How to use Decode Function in the case where column has string values

I have a view xxabc_v (shown below), I need to update the "Code" column to Null wherever it is N/A when "Value" column sum (900+(-900)=0) becomes zero for the "field_name" values (Demand A+Demand B) for the "Date" 01-Apr-21.
How can I put the decode logic to code column in the above case?
Table structure and expected output:
You don't want decode() because a much simpler method works:
select nullif(code, 'N/A')
This returns NULL when code takes on the specified value.
If you actually want to change the data, then you want update:
update t
set code = NULL
where code = 'N/A';
EDIT:
I see, you have an extra condition. So, use case:
(case when code = 'N/A' and
sum(value) over (partition by id, date) = 0
then NULL
else code
end)
I assumed that you need date wise id wise sum when to sum(). Please check this out:
select date,id,(case when sum(value)over(partition by date,id)=0 and code='N/A' then NULL
else Code end)code, field_name,value
from tablename

Snowflake if String Pattern replace

I have column which should only contain numbers[0-9], But in some cases we started see alphanumeric[eg:p8eSadfghrc] values in that column.
I wanna write a condition where if the value is not completely numeric{0-9}, i wanna replace it with another value from another column.
Something like this?
update t
set col = <other value>
where regexp_like(col, '[^0-9]');
This updates the data. You could also just do this in a query:
select t.*,
(case when regexp_like(col, '[^0-9]') then <other value> else col end)
from t;
In Snowflake, I would recommend try_to_decimal(). It attempts to convert the number to a decimal value (you control the target precision and scale with arguments) and rturns null if that fails:
select t.*, case when try_to_decimal(mycol) is null then myothercol else mycol end newcol
from mytable
If you want an update statement:
update mytable
set mycol = myothercol
where try_to_decimal(mycol) is null
When given no second and third argument, the number of allowed digits is 38, with 0 decimals (which seems to be what you want).

Visual Studio 2008 Case Expression using null

I'm trying to right a report that lets a user select either 'all values including null' or 'all values excluding null'. I placed a case expression in the where section. It doesn't work correctly for two reasons:
I can't pull the values of null and is not null at the same time.
In both cases it ends up pulling all values including null for the first one and only null values for the second.
Where
((CASE WHEN #nullvalue = 1 THEN check_rtn_void_dte end is not null) OR (CASE WHEN #nullvalue = 2 THEN check_rtn_void_dte end is null))
Is there a operator I can use that will pull null and is not null in one statement? Also, why is the first case pulling all data including null values?
Perhaps something like this would be simpler...
SELECT *
FROM MyTable
WHERE (#nullvalue = 2 OR check_rtn_void_dte IS NOT NULL)
That should pull out all results if #nullvalue = 2, or only non-NULL values if #nullvalue is something else.