Count of null values in all columns in total - sql

Have 100 columns where want to find null values in all column in total.
FindNull functon helps me to convert 'null'to '1' to be able to count them
Here is my code:
(select totalAmountOfNull =
(select count(*) from (select
countOfNull=
[dmt].[findNull](column1) +
[dmt].[findNull](column2) +
[dmt].[findNull](column3) )
from dmt.tableName ) as t10 where t10.totalAmountOfNull = 3
And Answer is wrong, due to '3'. The Main problem is that I do have 100 columns in one table and want to find all null values in total. But this code gives me wrong number.

In SQL Server, you can use apply:
select count(*)
from t cross apply
(values (t.col1), (t.col2), (t.col3), . . . ) v(col)
where v.col is null;
You need to list all the columns in the values() clause.

Related

Modify T-SQL Query to include/exclude colums depending on other columns value

I have the below query, that I need some help modifying. In the below Query I get the number of columns that are not null and the percentage:
SELECT COUNT(v.col) as num_not_null, COUNT(v.col) * 1.0 / COUNT(*) * 100 as percent_not_null, COUNT(*) as toltalColsNeedsFilled
FROM EFP_EmploymentUser t
CROSS APPLY (VALUES (t.ITAdvicedFirst),
(t.ITAdvicedSecond),
(t.ITDepartmentDone),
(t.CFOAdvicedFirst),
(t.CFOInfoProvided),
(t.CFOAdvicedSecond),
(t.CFODone),
(t.EconomyAdviced),
(t.EconomyDone),
(t.AcademyAdviced),
(t.AcademyDone),
(t.PublicatorAdviced),
(t.PublicatorDone),
(t.PortraitAdviced),
(t.PortraitDone),
(t.WhoIsWhoAdviced),
(t.WhoIsWhoDone),
(t.BogportalAdviced),
(t.BogportalDone),
(t.KeyCardAdviced),
(t.KeyCardDone) ) v(col)
WHERE ID = '19';
This returns in the case of ID 19:
num_not_null percent_not_null toltalColsNeedsFilled
5 23.809523809500 21
But I need to check if the following columns in the same table (Publicator,Bogportal,Academy) are filled with value 'yes', and depending on that I need to include or exclude som of the columns from my above query:
i.e.: IF Academy = YES then include t.AcademyAdviced & t.AcademyDone
IF Publicator= YES then include t.PublicatorDone & t.PortraitAdviced
IF Bogportal = YES then include t.BogportalAdviced & t.BogportalDone
Can anyone help me how to modifying the query to achive this? :-)
Best Regards
Stig
You can use UNION ALL and WHERE predicates to decide which columns to add to the unpivot:
SELECT COUNT(v.col) as num_not_null, COUNT(v.col) * 1.0 / COUNT(*) * 100 as percent_not_null, COUNT(*) as toltalColsNeedsFilled
FROM EFP_EmploymentUser t
CROSS APPLY (
SELECT * FROM
( VALUES (t.ITAdvicedFirst),
(t.ITAdvicedSecond),
(t.ITDepartmentDone),
(t.CFOAdvicedFirst),
(t.CFOInfoProvided),
(t.CFOAdvicedSecond),
(t.CFODone),
(t.EconomyAdviced),
(t.EconomyDone),
(t.PortraitAdviced),
(t.PortraitDone),
(t.WhoIsWhoAdviced),
(t.WhoIsWhoDone),
(t.KeyCardAdviced),
(t.KeyCardDone) ) v(col)
UNION ALL
SELECT *
FROM (VALUES (t.AcademyAdviced), (t.AcademyDone) ) v(col)
WHERE t.Academy = 'YES'
UNION ALL
SELECT *
FROM (VALUES (t.PublicatorDone), (t.PortraitAdviced) ) v(col)
WHERE t.Publicator = 'YES'
UNION ALL
SELECT *
FROM (VALUES (t.BogportalAdviced), (t.BogportalDone ) ) v(col)
WHERE t.Bogportal = 'YES'
) v
WHERE t.ID = '19';

Find all rows where there is another row which has in same field value from to-be-found-row +1

I have the following table (irrelevant fields and rows emitted for clarity):
customerID MediaIDdec
-------------- ----------------------
. .
. .
. .
16253 453456691
36178 453456692
24352 671254112
81432 226124312
44513 226124313
31336 226124314
64231 453653811
. .
. .
. .
The query should return all rows (row1) where MediaIDdec within another row (row2) is MediaIDdec (Row1) + 1 .
From the above example table, this would return:
16253 453456691 (because there is MediaIDdec+1 within row with customerID 36178)
81432 226124312 (because there is MediaIDdec+1 within row with customerID 44513)
44513 226124313 (because there is MediaIDdec+1 within row with customerID 31336)
My SQL skills are honestly not sufficient to solve such a query.
Hint: The table is sorted after MediaIDdec.
Your help is greatly appreciated.
You could use exists:
select t.*
from mytable t
where exists (select 1 from mytable t1 where t1.MediaIDdec = t.MediaIDdec + 1)
If MediaIDdec has no duplicates, an alternative is lead():
select *
from (
select t.*, lead(MediaIDdec) over(order by MediaIDdec) leadMediaIDdec
from mytable t
) t
where leadMediaIDdec = MediaIDdec + 1
In case you find a join based solution easier to digest
select t1.*
from t t1
join t t2 on t2.MediaIDdec = t1.MediaIDdec + 1
This approaches uses the LEAD function
with lead_cte as (
select *, lead(MediaIDdec) over (order by MediaIDdec)-MediaIDdec MediaIDdec_lead_diff
from tTable)
select *
from lead_cte
where MediaIDdec_lead_diff=1;

Given a specific column value, merge two columns in T-SQL

I have a table with the following content (simplified):
And this is the desired result:
In short, the first column has hundreds of values and sometimes repeated, for a given value of IDPRODUCTFIRST I want a RESULT column with the given value + the values ​​of IDPRODUCTSECOND.
SELECT IDPRODUCTSECOND AS RESULT
FROM [SCIOHIST].[dbo].[RELATIONPRODUCTMATCHES]
WHERE IDPRODUCTFIRST = 228697
With the query above, I can only get the values ​​from the second column, how could I add to the result column the given value (e.g. 228697) from the first column?
One method is to unpivot and select distinct values:
SELECT DISTINCT v.RESULT
FROM [SCIOHIST].[dbo].[RELATIONPRODUCTMATCHES] RPM CROSS APPLY
(VALUES (IDPRODUCTFIRST), (IDPRODUCTSECOND)) V(RESULT)
WHERE IDPRODUCTFIRST = 228697;
SELECT DISTINCT IDPRODUCTFIRST AS RESULT
FROM [SCIOHIST].[dbo].[RELATIONPRODUCTMATCHES]
--WHERE IDPRODUCTFIRST = 228697
UNION
SELECT DISTINCT IDPRODUCTSECOND AS RESULT
FROM [SCIOHIST].[dbo].[RELATIONPRODUCTMATCHES]
--WHERE IDPRODUCTFIRST = 228697
where clauses can exist or not.
IF you want duplicate value in both column are in your result you can use from "UNION ALL" instead of "UNION".
You can use Union
; With cteProd
as
(
SELECT IDPRODUCTFIRST, IDPRODUCTSECOND
FROM [SCIOHIST].[dbo].[RELATIONPRODUCTMATCHES]
)
Select RESULT from
(
SELECT IDPRODUCTFIRST, IDPRODUCTFIRST AS RESULT
FROM cteProd
Union
SELECT IDPRODUCTFIRST, IDPRODUCTSECOND AS RESULT
FROM cteProd
) Q
WHERE IDPRODUCTFIRST = 228697
Here is the fiddle
Yet another option is UNPIVOT
Example
Declare #YourTable Table ([IDPRODUCTFIRST] varchar(50),[IDPRODUCTSECOND] varchar(50)) Insert Into #YourTable Values
(228697,228699)
,(228697,228701)
Select Distinct Result
From (Select [IDPRODUCTFIRST],[IDPRODUCTSECOND]
From #YourTable
Where [IDPRODUCTFIRST] = 228697
) a
Unpivot ( Result for Item in ([IDPRODUCTFIRST],[IDPRODUCTSECOND]) ) unp
Returns
Result
228697
228699
228701

Checking distinct values on column level

I have four columns coming from my query. My requirement is to check if the values of all the columns are different then only select the result.
I have written this query and it is working fine. But I was just wondering if there is any better or shortcut way to achieve this
select FO, AFO, CO, ACO from mytable
where
(fo<>afo or (fo is null or afo is null))
and
(fo<>co or (fo is null or co is null))
and
(fo<>aco or (fo is null or aco is null))
and
(afo<>co or (afo is null or co is null))
and
(afo<>aco or (afo is null or aco is null))
and
(co<>aco or (co is null or aco is null))
Hmmm . . . you seem to want the four values to be different or NULL. A different method uses apply:
select t.*
from mytable t cross apply
(select count(*)
from (values (t.afo), (t.fo), (t.co), (t.aco)
) v(val)
where val is not null
having count(*) = count(distinct val)
) x;
This removes the NULL values and then checks that the remaining ones are all distinct.

Fetch unique combinations of two field values

Probably it has been asked before but I cannot find an answer.
Table Data has two columns:
Source Dest
1 2
1 2
2 1
3 1
I trying to come up with a MS Access 2003 SQL query that will return:
1 2
3 1
But all to no avail. Please help!
UPDATE: exactly, I'm trying to exclude 2,1 because 1,2 already included. I need only unique combinations where sequence doesn't matter.
For Ms Access you can try
SELECT DISTINCT
*
FROM Table1 tM
WHERE NOT EXISTS(SELECT 1 FROM Table1 t WHERE tM.Source = t.Dest AND tM.Dest = t.Source AND tm.Source > t.Source)
EDIT:
Example with table Data, which is the same...
SELECT DISTINCT
*
FROM Data tM
WHERE NOT EXISTS(SELECT 1 FROM Data t WHERE tM.Source = t.Dest AND tM.Dest = t.Source AND tm.Source > t.Source)
or (Nice and Access Formatted...)
SELECT DISTINCT *
FROM Data AS tM
WHERE (((Exists (SELECT 1 FROM Data t WHERE tM.Source = t.Dest AND tM.Dest = t.Source AND tm.Source > t.Source))=False));
your question is asked incorrectly. "unique combinations" are all of your records. but i think you mean one line per each Source. so it is:
SELECT *
FROM tab t1
WHERE t1.Dest IN
(
SELECT TOP 1 DISTINCT t2.Dest
FROM tab t2
WHERE t1.Source = t2.Source
)
SELECT t1.* FROM
(SELECT
LEAST(Source, Dest) AS min_val,
GREATEST(Source, Dest) AS max_val
FROM table_name) AS t1
GROUP BY t1.min_val, t1.max_val
Will return
1, 2
1, 3
in MySQL.
To eliminate duplicates, "select distinct" is easier than "group by":
select distinct source,dest from data;
EDIT: I see now that you're trying to get unique combinations (don't include both 1,2 and 2,1). You can do that like:
select distinct source,dest from data
minus
select dest,source from data where source < dest
The "minus" flips the order around and eliminates cases where you already have a match; the "where source < dest" keeps you from removing both (1,2) and (2,1)
Use this query :
SELECT distinct * from tabval ;