First column with NULL value in a table - sql

I would like to get to know how I can get the first column with NULL value from the left for each row in my table, I've tried with SELECT CASE but it doesn't work the way I would like.
Guys, I'd like to be crystal-clear about what I want to accomplish. I have a table with 22 columns and there are rows in which last 10 columns have NULL values but I need to get to know only a name of the first column from the left with NULL value.

You get the value from the first non-NULL column using coalesce():
select coalesce(col1, col2, col3, . . .)
You can get the name using case logic:
select (case when col1 is not null then 'col1'
when col2 is not null then 'col2'
. . .
end)

Just specify NULL as your first field selection.
SELECT NULL, FieldA, FieldB, FieldC etc
FROM yourtable

The only general approach here is case statement:
Case
when col1 is null then 'col1'
when col2 is null then 'col2'
when col3 is null then 'col3'
end as frst_null
This way frst_null would contain the name of the first column containing Null value. You can order columns whichever order you like.

Related

How to not display even one column is null in table

I have table like below:
I want result like even one column is null or empty string those records should not be display.
I want results like below:
select * from WHERE col1 IS NOT NULL AND col2 IS NOT NULL AND col3 IS NOT NULL AND col4 IS NOT NULL AND col5 IS NOT NULL....AND col9 IS NOT NULL
If you wanted an efficient way to do this, then one method would be a persistent computed column:
alter table t
add numNulls as ( (case when col1 is null then 1 else 0 end) +
(case when col2 is null then 1 else 0 end) +
(case when col3 is null then 1 else 0 end) +
. . .
) persisted;
You can index this column:
create index t_numNulls on t(numNulls);
And then you can use this in the select:
select t.*
from t
where num_nulls = 0;
That said, I suspect that your real problem is the data model. I am guessing that those 90 columns are really an "array" -- that is, all the same entity. These should be implemented as separate rows in a junction table.

Condition to get the NULL values and Blank values

I need help in creating the condition in stored procedure.
I have a two columns in my sp named col1,col2 and actually i have a data in my view named[SampleData] and in this view i have one column [col_new] which has both NULL values and Blank Values.
The Condition is:
If the [col_new] has an NULL, then display the [col_new] NULL in the col1 field.
If the [col_new] has a Blank, then display the [col_new] Blank in the col2 field.
So how can i add the condition here using if and else in CASE Condition?
Do you just want case expressions?
select (case when col_new is null then '[col_new] is null' end) as col1,
(case when col_new = '' then '[col_new] is blank' end) as col2
from SampleData;

Multiple Case Statements - Function/Sproc

I wish to create a table with many fields. And I need to do multiple case statement on each field. Please help me with a clean way (Function/Stored Proc) to do it, instead of writing case statement over and over.
Below is an example SQL.
SELECT
COALESCE(CASE WHEN Col1 = 'XXX' THEN 'YYY' ELSE NULL END,
CASE WHEN Col1 IN ('AAA','BBB') AND Col2 IS NULL THEN 'ZZZ' ELSE NULL END,
CASE WHEN Col1 = 'CCC' THEN 'DDD' ELSE Col2 END ) AS col_i
.
.
.
FROM table
Within a single query, you can use apply (or a subquery or CTE):
SELECT v.col_i
FROM table t CROSS APPLY
(VALUES (CASE . . . )
) v(col_i)
If you want this generally available, then don't use a function, use a computed column:
alter table t add col_i as
(case . . . );
This would then be available to anyone using the table.
I think we can rewrite your logic into a single CASE expression:
CASE WHEN Col1 = 'XXX'
THEN 'YYY'
WHEN Col1 IN ('AAA', 'BBB') AND Col2 IS NULL
THEN 'ZZZ'
WHEN Col1 = 'CCC'
THEN 'DDD'
ELSE Col2 END
What makes this work is that your ELSE values are NULL (except for the very last CASE expression), which logically means that COALESCE would just rollover to the next CASE expression.

How to find count of multiple columns in sql group by id?

I have a table with schema like below:
root
|id
|name
|col1
|col2
|...
|col30
Conditions are that multiple rows can have the same name (they're not primary key - the key is the ID). Values in col1-col30 will be some string, or it can have the string "null".
I'm interested in the number of columns filled in for each name.
For example,
if name "test1" has col1-5 filled in a row, and another row has "test1" and have col1, 3, 10, 6 filled in (and the rest of unfilled columns are just string value "null"), "test1" should have value 9.
I'm pretty new to SQL and have been looking this up.. Please help.
Give this a try:
SELECT
name,
CASE WHEN col1_max IS NOT NULL THEN 1 ELSE 0 END + -- Only include non-NULL values
CASE WHEN col2_max IS NOT NULL THEN 1 ELSE 0 END
FROM (
SELECT
name,
MAX(col1) AS col1_max, -- Non-NULL values come before NULL
MAX(col2) AS col2_max
FROM MyTable
GROUP BY name
) src
You can add more the rest of the columns to fit your case.
Updated
I just realized your NULL case is with a "null" string. Modified:
SELECT
name,
CASE WHEN col1_max IS NOT NULL THEN 1 ELSE 0 END + -- Only include non-NULL values
CASE WHEN col2_max IS NOT NULL THEN 1 ELSE 0 END
FROM (
SELECT
name,
MAX(CASE WHEN col1 = 'null' THEN NULL ELSE col1 END) AS col1_max, -- Non-NULL values come before NULL
MAX(CASE WHEN col2 = 'null' THEN NULL ELSE col2 END) AS col2_max
FROM MyTable
GROUP BY name
) src
First you unpivot your table and count those rows that have not null values. In postgres, you can achieve this with unnest. I have only used col1..7 -- change to upto col30 in your case
WITH t AS(
SELECT id,name,
unnest(array['col1', 'col2', 'col3', 'col4', 'col5', 'col6', 'col7']) AS colname,
unnest(array[col1, col2, col3, col4, col5, col6, col7]) AS colvalue
FROM your_table)
SELECT id, name,
SUM(CASE WHEN colvalue IS NULL THEN 0 ELSE 1 END) AS count_filled
FROM t
GROUP BY 1,2;

how to know which column is matched when filter the records by multiple columns compare

I have a table "table1" like
NAME COL1 COL2 COL3 COL4
A 1 2 3 4
I want to filter the table by
"SELECT * FROM table1 where (COL1=1 OR COL2=1 OR COL3=1 OR COL4=1)"
I expect the result is
NAME COL_NAME
A COL1
Is that possible by SQL statement?
You are not limited to selection of columns in your select list, you can use expressions. For example, you can use this:
SELECT
NAME, -- More columns as needed
CASE
WHEN COL1=1 THEN 'COL1'
WHEN COL2=1 THEN 'COL2'
WHEN COL3=1 THEN 'COL3'
WHEN COL4=1 THEN 'COL4'
ELSE NULL END AS COL_MATCH
FROM table1 where (COL1=1 OR COL2=1 OR COL3=1 OR COL4=1)