How can I use pivot to find the records with the most columns populated? - sql

I have a problem where I have 5 columns.
What I want to do is add a count on the end with the number of columns where there is no null value.
I am trying to use pivot as this seems to be the most logical SQL clause. Any ideas on this? I haven't used Pivot in many instances so this is new for me.

An inline pivot/conditional aggregate and a COUNT seems to be what you want here. As all your columns have different data types, you need to also use some CASE expressions. Something like this:
SELECT ID,
a,
...
(SELECT COUNT(V.C)
FROM (VALUES(CASE WHEN a IS NOT NULL THEN 1 END),
(CASE WHEN b IS NOT NULL THEN 1 END),
(CASE WHEN c IS NOT NULL THEN 1 END),
(CASE WHEN d IS NOT NULL THEN 1 END),
(CASE WHEN e IS NOT NULL THEN 1 END),
(CASE WHEN f IS NOT NULL THEN 1 END))V(C)) AS NonNullColumns
FROM dbo.YourTable;

Related

Coalesce in duplicated values

I have a table like this:
And I want to transform for each value a column, to become something like this:
If I do a query like this:
Select "_sdc_source_key_id",
COALESCE(value='Integrity',null) as cia_security
,COALESCE (value='Confidentiality',null) as cia_conf
,COALESCE (value='Availability',null) as cia_availability
FROM
staging_jira.issues__fields__customfield_10420
where _sdc_source_key_id='201496'
That is my result, I have duplicated rows:
What should be the best solution to achieve my transformation?
Thanks a lot!
You can GROUP By "_sdc_source_key_id" and use MAX of your values
Select "_sdc_source_key_id",
MAX(COALESCE(value='Integrity',null)) as cia_security
,MAX(COALESCE (value='Confidentiality',null)) as cia_conf
,MSX(COALESCE (value='Availability',null)) as cia_availability
FROM
staging_jira.issues__fields__customfield_10420
where _sdc_source_key_id='201496'
GROUP BY "_sdc_source_key_id"
If your databse doesn't support MAX from boolean switch to Int
Select "_sdc_source_key_id",
MAX(CASE WHEN value='Integrity' THEN 1 ELSE null END) as cia_security
,MAX(CASE WHEN value='Confidentiality' THEN 1 ELSE null END) as cia_conf
,MSX(CASE WHEN value='Availability' THEN 1 ELSE null END) as cia_availability
FROM
staging_jira.issues__fields__customfield_10420
where _sdc_source_key_id='201496'
GROUP BY "_sdc_source_key_id"

Create a Query to check if any Column in a table is Null

I have zero experience with SQL but am trying to learn how to validate tables. I am trying to see within a table if any of the columns are null.
Currently I have been going with a script that is just counting the number of nulls. I am doing this for each column. Is there a better script that I can use to check all the columns in a table?
select count(id) from schema.table where id is not null
If there are 100 records I would expect all columns to come back with 100 but if one column is null it will show a 0.
You can count each column in a single query by using sum and case:
select
sum(case when Column1 is null then 1 else 0 end) Column1NullCount
, sum(case when Column2 is null then 1 else 0 end) Column2NullCount
-- ...
, sum(case when ColumnN is null then 1 else 0 end) ColumnNNullCount
from MyScheme.MyTable

SQL Case When Statement for Id with multiple rows

I have a table like so
Id Code
1 03J0
1 0304
1 03HI
2 033I
2 03J5
3 03J4
4 030H
I want to do a case when statement, when there is any occurrence where the Id has a Code that is like '%03J' then Happy otherwise Sad. How do I do this when an Id has multiple rows of different codes?
Intended output
Id Emotion
1 Happy
2 Happy
3 Happy
4 Sad
Is this what you want?
select id,
(case when sum(case when code like '03J%' then 1 else 0 end) > 0 then 'Happy' else 'Sad' end) as emotion
from t
group by id;
Using the ordering of strings, you can simplify this to:
select id,
min(case when code like '03J%' then 'Happy' else 'Sad' end) as emotion
from t
group by id;
Here is a db<>fiddle.
Using self-join. Judging from your sampple data, I think you want '03J%' instead of '%03J'
select distinct a.id, case when b.code is not null then 'Happy' else 'Sad' end as emotion
from mytable a
left join mytable b on a.id=b.id and b.code like '03J%';

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
)
;

SQL (TSQL) - Select values in a column where another column is not null?

I will keep this simple- I would like to know if there is a good way to select all the values in a column when it never has a null in another column. For example.
A B
----- -----
1 7
2 7
NULL 7
4 9
1 9
2 9
From the above set I would just want 9 from B and not 7 because 7 has a NULL in A. Obviously I could wrap this as a subquery and USE the IN clause etc. but this is already part of a pretty unique set and am looking to keep this efficient.
I should note that for my purposes this would only be a one-way comparison... I would only be returning values in B and examining A.
I imagine there is an easy way to do this that I am missing, but being in the thick of things I don't see it right now.
You can do something like this:
select *
from t
where t.b not in (select b from t where a is null);
If you want only distinct b values, then you can do:
select b
from t
group by b
having sum(case when a is null then 1 else 0 end) = 0;
And, finally, you could use window functions:
select a, b
from (select t.*,
sum(case when a is null then 1 else 0 end) over (partition by b) as NullCnt
from t
) t
where NullCnt = 0;
The query below will only output one column in the final result. The records are grouped by column B and test if the record is null or not. When the record is null, the value for the group will increment each time by 1. The HAVING clause filters only the group which has a value of 0.
SELECT B
FROM TableName
GROUP BY B
HAVING SUM(CASE WHEN A IS NULL THEN 1 ELSE 0 END) = 0
If you want to get all the rows from the records, you can use join.
SELECT a.*
FROM TableName a
INNER JOIN
(
SELECT B
FROM TableName
GROUP BY B
HAVING SUM(CASE WHEN A IS NULL THEN 1 ELSE 0 END) = 0
) b ON a.b = b.b