views:

60

answers:

5

Assume the following table:

ID | Item1 | Item2 | Item3 | Item4 | Item5
------------------------------------------
A  | NULL  | NULL  | YES   | YES   | NULL
B  | NULL  | NULL  | NULL  | YES   | NULL
C  | NULL  | NULL  | NULL  | NULL  | NULL

I want to return the following data set:

ID  | Count
------------
A   | 2
B   | 1
C   | 0

Basically, I want a count how many of the columns of Item1-5 are NOT NULL for that ID

How can I do this in MS-SQL?

A: 

This should do it:

SELECT ID, (case when item1 is null then 0 else 1 end)+
           (case when item2 is null then 0 else 1 end)+
           (case when item3 is null then 0 else 1 end)+
           (case when item4 is null then 0 else 1 end)+
           (case when item5 is null then 0 else 1 end) AS Count 
FROM Table
ORDER BY ID

I hope this is a hypothetical question and not an actual production table.

Michael Goldshteyn
It's actually a really weird one-time sales query wanting to know if a product has certain properties not set to null
Bryan Denny
Thanks Joe for adding the ends :) .
Michael Goldshteyn
you will get an error with this code, because "END" is required for each CASE. Also, the "when NULL" will not work and each row will return a count of 5.
KM
@Joe Stefanelli, you fixed the "ends" but **this query STILL returns the wrong results.** Use the sample code from my answer and plug this query in and try it yourself. the CASE is ill formed, should be `CASE WHEN item1 IS NULL then...` like in my answer.
KM
You're right once again. I edited my answer accordingly.
Michael Goldshteyn
+2  A: 

Not tested, but something like this should work.

SELECT
  Id,
  SUM(
    CASE WHEN Item1 is NULL THEN 0 ELSE 1 END
    +
    CASE WHEN Item2 is NULL THEN 0 ELSE 1 END
    +
    CASE WHEN Item3 is NULL THEN 0 ELSE 1 END
    +
    CASE WHEN Item4 is NULL THEN 0 ELSE 1 END
    +
    CASE WHEN Item5 is NULL THEN 0 ELSE 1 END
    ) 'Count'
FROM 
   tableName
GROUP BY 
   Id
Phil Sandler
I could be wrong, but I'll BET that ID is a primary key, which means that the `SUM()` and `GROUP BY` are not needed and will just add overhead to the query
KM
I thought the same thing, but didn't want to assume.
Phil Sandler
+2  A: 

Try:

DECLARE @YourTable table (ID char(1), Item1 varchar(3), Item2 varchar(3), Item3 varchar(3), Item4 varchar(3), Item5 varchar(3))
INSERT @YourTable VALUES ('A'  , NULL  , NULL  , 'YES' , 'YES' , NULL)
INSERT @YourTable VALUES ('B'  , NULL  , NULL  , NULL  , 'YES' , NULL)
INSERT @YourTable VALUES ('C'  , NULL  , NULL  , NULL  , NULL  , NULL)

SELECT
    ID, CASE WHEN ITEM1 IS NULL THEN 0 ELSE 1 END
       +CASE WHEN ITEM2 IS NULL THEN 0 ELSE 1 END
       +CASE WHEN ITEM3 IS NULL THEN 0 ELSE 1 END
       +CASE WHEN ITEM4 IS NULL THEN 0 ELSE 1 END
       +CASE WHEN ITEM5 IS NULL THEN 0 ELSE 1 END AS [Count]
    FROM @YourTable

OUTPUT:

ID   Count
---- -----------
A    2
B    1
C    0

(3 row(s) affected)
KM
A: 

Just another option: If you're in sql 2k5 or later you can also use an unpivot to count all non-null values. You won't get any rows for zero-counts directly from this query though. It does however save the tedium of case statements.

select
    ID, count(ItemCount) as ItemCount
from
(
    select ID, Item1, Item2, Item3, Item4, Item5
    from TableA a
) t
unpivot
(
    ItemCount for Item in
    (
        Item1, Item2, Item3, Item4, Item5
    )
) as unpvt
group by
    ID
ulty4life
A: 

Another technique.

SELECT
    ID, 
    (SELECT COUNT(C) FROM( 
            SELECT Item1 C 
            UNION ALL 
            SELECT Item2 
            UNION ALL 
            SELECT Item3 
            UNION ALL 
            SELECT Item4 
            UNION ALL 
            SELECT Item5)
             D)
AS [Count]
FROM @YourTable
Martin Smith