简体   繁体   中英

SQL Server query excude all null values

I am trying to form a query that would allow me to count only the rows that are not NULL

SELECT count(*) 
FROM jSettings 
WHERE linkToJData = '56211010105' 
  AND tblName1 IS NOT NULL 
  AND tblName2 IS NOT NULL;

I have columns called tblName1 - tblName25 .

All I am looking to accomplish is to find out how many tblNameXX there are without a NULL .

The query above only produces a 1 every time.

SELECT
 sum(case when tblName1 is null then 0 else 1 end) +
 sum(case when tblName2 is null then 0 else 1 end) +
 sum(case when tblName3 is null then 0 else 1 end) +
 sum(case when tblName4 is null then 0 else 1 end) +
 sum(case when tblName5 is null then 0 else 1 end) +
 sum(case when tblName6 is null then 0 else 1 end) +
 sum(case when tblName7 is null then 0 else 1 end) +
 sum(case when tblName8 is null then 0 else 1 end)   
FROM jSettings 
WHERE linkToJotData = '56211010105'

No need to union multiple result sets. This technique only requires a single pass over the data.

The issue here is with the AND condition. If you provide AND condition you will get only those records where all the values for TBLNAME1..25 is populated. But your requirement is to find individually how many records are having not null value.

you can use union for each columns and get the count separately and them sum up them to get the total count of not null values.

Let me know if this is what is intended.

That's because you're looking for records where both tblName1 and tblName2 are null. Is that your intention? If it's not, then you could try:

Select count(*) totalrows 
From jSettings 
where linkToJData = '56211010105' 
  and (tblName1 IS NOT NULL OR tblName2 IS NOT NULL)

you can do follows

declare @Data xml = 
(
    select *
    from jSettings
    where linkToJData = '56211010105'
    for xml path('row')
)

select count(*)
from @Data.nodes('/row/*[local-name(.) != "linkToJData"]') as T(C);

if you don't want to use xml, you can use this query:

select count(*)
from jSettings as j
    outer apply (values
        (j.tblName1),
        (j.tblName2),
        (j.tblName3),
        (j.tblName4),
        (j.tblName5)
    ) as C(name)
where j.linkToJData = '56211010105' and c.name is not null;

If you have many columns ans don't want to specify it manually:

declare @stmt nvarchar(max)

select @stmt =
    isnull(@stmt + ', ', '') + '(j.' + c.name + ')'
from sys.syscolumns as c
where id = object_id('dbo.jSettings') and c.name <> 'linkToJData'

select @stmt = '
select count(*)
from jSettings as j
    outer apply (values ' + @stmt + ') as C(name)
where j.linkToJData = @linkToJData and c.name is not null'

exec sp_executesql
    @stmt = @stmt,
    @params = N'@linkToJData nvarchar(128)',
    @linkToJData = '56211010105'

sql fiddle demo

I suggest 1st or 3rd one - so you don't have to change your query for new columns

Select 'tblName1',count(*) totalrows1 
From jSettings 
where linkToJData = '56211010105' 
  and tblName1 IS NOT NULL
union
Select 'tblName2',count(*) totalrows2
From jSettings 
where linkToJData = '56211010105' 
  and tblName2 IS NOT NULL

Try this code to get individual counts.

SELECT
 sum(case when tblName1 is null then 0 else 1 end) +
 sum(case when tblName2 is null then 0 else 1 end) +
 sum(case when tblName3 is null then 0 else 1 end) +
 sum(case when tblName4 is null then 0 else 1 end) +
 sum(case when tblName5 is null then 0 else 1 end) +
 sum(case when tblName6 is null then 0 else 1 end) +
 sum(case when tblName7 is null then 0 else 1 end) +
 sum(case when tblName8 is null then 0 else 1 end)   
FROM jSettings 
WHERE linkToJotData = '56211010105' 

This does report 7 which would be correct since the only table that has NULL is tblName8.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM