Check multiple columns with value NULL in SQL Server - sql

Currently I have the following sql statement:
SELECT CASE
WHEN sd.GV01 IS NULL
AND sd.GV02 IS NULL
AND sd.GV03 IS NULL
AND sd.GV04 IS NULL
AND sd.GV05 IS NULL
AND sd.CountryId = '4' THEN 4
END AS rating
FROM masterData sd
I tried to take the same way with a more short definition:
SELECT CASE
WHEN NULL IN (sd.GV01, sd.GV02, sd.GV03, sd.GV04, sd.GV05)
AND sd.CountryId = '4' THEN 4
END AS rating
FROM masterData sd
But I don't get return values, why? Can someone give me a better solution?

Your method is fine. Almost any comparison of NULL values returns NULL -- which is treated as false.
You could use COALESCE():
SELECT (CASE WHEN COALESCE(sd.GV01, sd.GV02, sd.GV03, sd.GV04, sd.GV05) IS NULL AND
sd.CountryId = '4'
THEN 4
END) AS rating
FROM masterData sd;

Related

how remove null result after UNION

Suppose to have a union, I have query a and query b
query A....
UNION
select (case when address is null then address else null end)......
the query works correctly but there is only a problem.
when case address!=null I read in the result null row:
address(column)
london square 3
new york 2
null
There is some way that when I do union null value are not returned? Anyone can help me?
One option is to use your UNION query as a subquery and return rows that aren't null.
select address
from (-- this is your current query
select address from some_table
union
select address from some_other_table
)
where address is not null
If you do:
select (case when address is null then address else null end) ...
Then:
if address is NULL then the THEN clause will be returned which is the NULL value in the address column; and
if address is not NULL then the ELSE clause will be returned which is a NULL value.
So you will ALWAYS be returning NULL.
You could simplify your query to:
SELECT NULL ...
If you want to return a non-NULL value then swap the terms in the CASE:
select case when address is null then null else address end ...
However, that can just be simplified to:
select address ...
I assume you are wanting a WHERE clause:
UNION
SELECT address
FROM table_name
WHERE address IS NOT NULL;
However, without a complete example it is difficult to determine what your exact goal is.

how do you check for nulls in any column in an entire table in SQL

I would like to check if any of my columns in a table have any null values. I am sure there is a quicker way than how I am doing it at the moment. I just want to see if there is a NULL in ANY column however my table has a lot of columns, is there a simple and quick way?
This way I have written so far works but it takes a long time to do for every column (hence the etc etc)
select
sum(case when id is null then 1 else 0 end) as id,
sum(case when name is null then 1 else 0 end) as name,
sum(case when review_count is null then 1 else 0 end) as review_coun,
sum(case when positive_review is null then 1 else 0 end) as
positive_review,
sum(etc etc
from user
I don't know if this will work for your scenario, but it's an option. You can CAST all your columns as a string and then concatenate them together. If you concatenate a NULL value with a string, it will return NULL.
SELECT 'Y'
WHERE EXISTS( -- Check if there are any NULL rows
SELECT
CAST(c1 AS CHAR(1)) ||
CAST(c2 AS CHAR(1)) ||
...
AS MyColumns
WHERE MyColumns IS NULL
)
;

Case expression with multiple results

I am looking for a way to actually create some duplication in my results in MS SQL Server. I understand that typically you are looking for ways to not create duplication, but in this examples I need all the individual rows returned.
I am working with a table with about 10 million rows and 33 columns. The table consists of an ID in the first column and the remainder of the columns have either 'Y' or 'NULL' in them - a HUGE majority of the columns are NULL.
Of the 10 million rows 8 million of them only have a single 'Y' per row with the remaining 2 million rows having more than one column with a 'Y' in a row.
For the rows with a single 'Y' a basic case expression works perfectly fine to create a single column of results .
Here is my problem though - I want two rows, one for each 'Y' if there is more than one 'Y' in a row.
Below is a small de-identified sample.
ID FLAG1 FLAG2 FLAG3 FLAG4 FLAG5
188 NULL NULL NULL NULL NULL
194 Y NULL NULL NULL NULL
200 Y NULL NULL NULL Y
I am attempting to use a Case Expression like this.
Select
ID
,Case
When [FLAG1] = 'Y'
Then 'FLAG1'
When [FLAG2] = 'Y'
Then 'FLAG2'
End as 'Service_Line'
What I want is a result that looks like this.
ID Service_Line
194 FLAG1
200 FLAG1
200 FLAG5
My problem is that the Case expression only returns the first result so I end up with this.
ID Service_Line
194 FLAG1
200 FLAG1
Is a Case Expression appropriate for what I am trying to accomplish or should I be trying to go about this some other way?
A case is not appropriate. A general SQL approach would be:
select id, 'FLAG1' as flag
from t
where flag1 = 'Y'
union all
select id, 'FLAG2' as flag
from t
where flag2 = 'Y'
union all
select id, 'FLAG3' as flag
from t
where flag3 = 'Y'
. . .
There are other (more efficient) methods, but those depend on the database you are using.
I should note: case is the right approach if you want the values in a single row:
select id,
concat( case when flag1 = 'Y' then 'FLAG1 ' else '' end,
case when flag2 = 'Y' then 'FLAG2 ' else '' end,
case when flag3 = 'Y' then 'FLAG3 ' else '' end,
. . .
) as flags
from t;
Of course, the syntax for concat() can vary among databases (concat() itself is ANSI standard). You can also trim off the last space.

SQL ISNULL not working

I'm trying to display 00001 when the query result is null but the query still return null. I don't know whats wrong with my query.
EDIT:
Assuming OBRNo is 123-5678-10-13-1619 means LEN(a.OBRNo) is 19
SELECT TOP 1 CASE WHEN RIGHT(a.OBRNo, 5) = NULL THEN '00001' ELSE a.OBRNo
END as CaseWhen,
ISNULL(a.OBRNo, '00001') as ISNULL,
RIGHT(OBRNo, 5) as OrderBy
FROM tbl_T_BMSCurrentControl as a
WHERE LEN(a.OBRNo) = 20 and a.ActionCode = 1
ORDER BY OrderBy DESC
Compare with NULL with IS NULL / IS NOT NULL, not with = NULL.
SELECT TOP 1 CASE WHEN RIGHT(a.OBRNo, 5) IS NULL THEN '00001' ELSE a.OBRNo END
...
You could change this behaviour with SET ANSI_NULLS.
The reason why you can't compare with = by default is: NULL means undefined. Nothing is equal to unknown not even NULL. If you compare with NULL the result is unknown, hence also NULL.
Is your query returning any row?
Your ISNULL (x,y) should do what you expect but it looks like your WHERE is filtering all the records, due to the NULLS.
Try this:
SELECT TOP 1 CASE WHEN RIGHT(a.OBRNo, 5) = NULL THEN '00001' ELSE a.OBRNo
END as CaseWhen,
ISNULL(a.OBRNo, '00001') as ISNULL,
RIGHT(OBRNo, 5) as OrderBy
FROM tbl_T_BMSCurrentControl as a
WHERE (a.OBRNo IS NULL OR LEN(a.OBRNo) = 20) and a.ActionCode = 1
ORDER BY OrderBy DESC
LEN(a.OBRNo) being a.OBRNo NULL will be NULL so NULL = 20 will be NULL and NULL AND a.ActionCode = 1 will be NULL which when filtering is treated as FALSE

Impala SQL, return value if a string exists within a subset of values

I have a table where the id field (not a primary key) contains either 1 or null. Over the past several years, any given part could have been entered multiple times with one, or both of these possible options.
I'm trying to write a statement that will return some value if there is ever a 1 associated with the select statement. There are lots of semi-duplicate rows, some with 1 and some with null, but if there is ever a 1, I want to return true, and if there are only null values, I want to return false. I'm not sure how to code this though.
If this is my SELECT part,id from table where part = "ABC1234" statement
part id
ABC1234 1
ABC1234 null
ABC1234 null
ABC1234 null
ABC1234 1
I want to write a statement that returns true, because 1 exists in at least one of these rows.
The closest I've come to this is by using a CASE statement, but I'm not quite there yet:
SELECT
a1.part part,
CASE WHEN a2.id is not null
THEN
'true'
ELSE
'false'
END AS id
from table.parts a1, table.ids a2 where a1.part = "ABC1234" and a1.key = a2.key;
I also tried the following case:
CASE WHEN exists
(SELECT id from table.ids where id = 1)
THEN
but I got the error subqueries are not supported in the select list
For the above SELECT statement, how do I return 1 single line that reads:
part id
ABC1234 true
You can use conditional aggregation to check if a part has atleast one row with id=1.
SELECT part,'True' id
from parts
group by part
having count(case when id = 1 then 1 end) >= 1
To return false when the id's are all nulls use
select part, case when id_true>=1 then 'True'
when id_false>=1 and id_true=0 then 'False' end id
from (
SELECT part,
count(case when id = 1 then 1 end) id_true,
count(case when id is null then 1 end) id_false,
from parts
group by part) t