SQL SUM to ignore NULL value - sql

I have a table TEST_TABLE as follows:
Name x_col y_col
=======================
Jay NULL 2
This is a simplistic representation of a much larger issue but will suffice.
When I do the following query I get NULL returned
SELECT SUM(x_col + y_col) FROM TEST_TABLE WHERE Name='Jay'
I want it to be 2. I thought the SUM() method ignores NULL values. How can I ignore values that are null in this query? Or actually in general, as this is a problem for a lot of my algorithms.

You get NULL because NULL + 2 returns NULL. The SUM() has only one row, and if the + expression is NULL, then the SUM() returns NULL.
If you want NULL to be treated as 0, the use COALESCE():
SELECT SUM(COALESCE(x_col, 0) + COALESCE(y_col, 0))
FROM TEST_TABLE
WHERE Name = 'Jay';
One final note. If you start with your data and filtered out all rows, then the result will still be NULL. To get 0, you need an additional COALESCE():
SELECT COALESCE(SUM(COALESCE(x_col, 0) + COALESCE(y_col, 0)), 0)
FROM TEST_TABLE
WHERE Name = 'Jayden';

Use COALESCE to replace NULL with 0.
SELECT sum(coalesce(x_col, 0) + coalesce(y_col, 0)) FROM TEST_TABLE WHERE Name='Jay'

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

"!="/NOT perhaps not working properly in SQLite

I have a table with about a hundred rows. It has a column is_gallery that contains either 1, 0, or NULL. If I do...
SELECT * WHERE is_gallery != 1
or
SELECT * WHERE NOT (is_gallery = 1)
it excludes the rows where is_gallery is null. I can manage to get a proper response if I do
SELECT * WHERE (is_gallery = 0 OR is_gallery is null)
But shouldn't the "!=" or NOT work? Isn't there a way to just return the rows where is_gallery doesn't equal 1 without testing for every other possibility?
You can use the IS and IS NOT operators instead of = and !=. These treat NULL like a normal value.
SELECT * FROM yourTable WHERE is_gallery IS NOT 1
The best thing to use is coalesce as in:
SELECT *
WHERE coalesce(is_gallery,0) != 1;
what coalesce does, is replaces any null value in that column with the second parameter. In the example above, any nulls in the "is_gallery" column will be replaced with 0 before it is compared with 1. So will of course return true.
On NULL realize that a NULL value isn't equal to ANYTHING - not even NULL itself. It cannot be compared - so when "comparing", it always will return FALSE. On NULL, it has a special operator which is "IS NULL" or "IS NOT NULL"

Using COALESCE to handle NULL values in PostgreSQL

I have the following query
SELECT DISTINCT
pt.incentive_marketing,
pt.incentive_channel,
pt.incentive_advertising
FROM test.pricing pt
WHERE pt.contract_id = 90000
group by 1,2,3
order by pt.incentive_marketing;
The above query returns the o/p as shown in the attached image
However I want to replace all null values by 0 using COALESCE
Please let me know how this can be achieved in above SELECT query
Now I further modified the query using coalesce as below
SELECT
COALESCE( pt.incentive_marketing, '0' ),
COALESCE(pt.incentive_channel,'0'),
COALESCE( pt.incentive_advertising,'0')
FROM test.pricing pt
WHERE pt.contract_id = 90000
group by 1,2,3
the result of which is as attached in image 2.
I still receive one row with blank values
You can use COALESCE in conjunction with NULLIF for a short, efficient solution:
COALESCE( NULLIF(yourField,'') , '0' )
The NULLIF function will return null if yourField is equal to the second value ('' in the example), making the COALESCE function fully working on all cases:
QUERY | RESULT
---------------------------------------------------------------------------------
SELECT COALESCE(NULLIF(null ,''),'0') | '0'
SELECT COALESCE(NULLIF('' ,''),'0') | '0'
SELECT COALESCE(NULLIF('foo' ,''),'0') | 'foo'
If you're using 0 and an empty string '' and null to designate undefined you've got a data problem. Just update the columns and fix your schema.
UPDATE pt.incentive_channel
SET pt.incentive_marketing = NULL
WHERE pt.incentive_marketing = '';
UPDATE pt.incentive_channel
SET pt.incentive_advertising = NULL
WHERE pt.incentive_marketing = '';
UPDATE pt.incentive_channel
SET pt.incentive_channel = NULL
WHERE pt.incentive_marketing = '';
This will make joining and selecting substantially easier moving forward.

SQL minus 2 columns - with null values

I have this table (made from a SQL query):
Row 1 Row 2
2 1
3 NULL
And I want to minus the 2 columns, so I just select like this:
Select Row1 - Row2
From table
But then I get this result:
1
NULL
instead of:
1
3
How can I make it possible to get the last result?
Please try:
SELECT ISNULL([Row 1], 0) - ISNULL([Row 2], 0) from YourTable
For more Information visit ISNULL
The reason you got this is because Any Mathematical operation with NULL produces NULL So while doing operation all values should be read as NULL=0.
With ISNULL()
Hence
SELECT ISNULL([Row 1], 0) - ISNULL([Row 2], 0) from YourTable
The MySQL equivalent of ISNULL is IFNULL
If expr1 is not NULL, IFNULL() returns expr1; otherwise it returns
expr2.
Maybe also look at SQL NULL Functions
The ISNULL from MySQL is used to check if a value is null
If expr is NULL, ISNULL() returns 1, otherwise it returns 0.
in sql anything minus with NULL then it is always NULL so you need to convert NULL to Zero
SELECT ISNULL(ROW1,0)-ISNULL(ROW2,0) FROM YOUR_TABLE
Select Row1 - COALESCE(Row2,0)
From table

How to treat MAX() of an empty table as 0 instead of NULL

I try to select max value from table
SELECT MAX(cid) FROM itemconfiguration;
However when table itemconfiguration is empty the MAX(cid) statements is evaluated to NULL while i need a number. How to handle this and treat NULL as 0 ?
Just use Coalesce or NVL to handle NULLs.
The following code will return 0 if MAX(cid) is NULL
SELECT COALESCE(MAX(cid), 0)
FROM itemconfiguration
SELECT NVL(MAX(cid), 0) FROM itemconfiguration;
Can replace a number when max return null using ISNULL ,
ISNULL(MAX(cid),0) FROM itemconfiguration;