Count the number columns using NOT NULL in a case statement - sql-server

I need some help with my query...I am trying to get a count of names in each house, all the col#'s are names.
Query:
SELECT
House#,
COUNT(CASE WHEN col#1 IS NOT NULL THEN 1 ELSE 0 END) +
COUNT(CASE WHEN col#2 IS NOT NULL THEN 1 ELSE 0 END) +
COUNT(CASE WHEN col#3 IS NOT NULL THEN 1 ELSE 0 END) AS count
FROM
myDB
WHERE
House# IN (house#1, house#2, house#3)
GROUP BY
House#
Desired results:
house 1 - the count is 3
house 2 - the count is 2
house 3 - the count is 1
...with my current query the results for count would be just 3's

COUNT by design doesn't count NULL values.
SELECT House#,
COUNT(col1#) + COUNT(col2#) + COUNT(col3#) AS count
FROM myDB
WHERE House# IN (house#1,house#2,house#3)
GROUP BY House#;

Related

SUM values when conditions met

I have the following SQL Server table with the following data:
PRICE(decimal 9,2) PRICETYPE(int) EVENTDETAILID (int)
PRICE PRICETYPE EVENTDETAILID
------------------------------------------------
99 1 1
99 1 1
99 1 1
15 0 1
15 0 1
50 1 2
50 1 2
I want to SUM the PRICE of the results with the following conditions:
for each EVENTDETAILID, SUM every line with a pricetype is 0 and for every line per EVENTDETAILID pricetype is 1, then add it only 1 time.
For the above example the required output would be:
99 + 15 + 15 for eventDetailId = 1
50 for eventDetailsId = 2
I've tried the following but doesn't work as expected as I'm not able to add PRICE only once if PRICETYPE is 1:
SELECT
SUM(PRICE)
FROM
ReservationDetails
GROUP BY
eventDetail_id
You may phrase this as an aggregation (GROUP BY) query over the event detail ID. The sum can be broken into a conditional sum when the detail ID is 0, combined with the maximum price when the detail ID is 1. Since you told us that the price is always the same when PRICETYPE=1, therefore we can choose any single value.
SELECT
EVENTDETAILID,
SUM(CASE WHEN PRICETYPE = 0 THEN PRICE ELSE 0 END) +
MAX(CASE WHEN PRICETYPE = 1 THEN PRICE ELSE 0 END) AS total
FROM yourTable
GROUP BY
EVENTDETAILID
ORDER BY
EVENTDETAILID;
Demo

COUNT and COUNT DISTINCT for different groups

For a SQL Server based report,
Table:
CID Date ID Service Days
1 3/7/2016 1 Individual 3
2 4/5/2016 2 Individual 4
3 5/24/2016 1 Individual 3
4 4/4/2016 4 Group 2
5 4/4/2016 4 Group 2
6 2/18/2016 4 Group 2
7 5/5/2016 5 Group 1
8 5/5/2016 5 Group 1
I used this code:
SELECT
ID,
Service,
COUNT(WHEN Days = 4 THEN 1 END) AS '4Days',
COUNT(WHEN Days = 3 THEN 1 END) AS '3Days',
COUNT(WHEN Days = 2 THEN 1 END) AS '2Days',
COUNT(WHEN Days = 1 THEN 1 END) AS '1Day'
FROM Table T1
GROUP BY
ID,
Service
which gives me this Output:
ID Service 4Days 3Days 2Days 1Day
1 Individual 0 2 0 0
2 Individual 1 0 0 0
4 Group 0 0 3 0
5 Group 0 0 0 2
What I want to do is not count the Group services as separate services for separate individuals, but just as one service per group. A Count Distinct used with the Date or ID could help me do that but I don't know how to make that play with the Individual services where I just wanna count them individually and not using DISTINCT. So the desired output is:
ID Service 4Days 3Days 2Days 1Day
1 Individual 0 2 0 0
2 Individual 1 0 0 0
4 Group 0 0 2 0
5 Group 0 0 0 1
I'll edit the post in case I oversimplified the problem since this is dummy data.
Looks like you could use distinct this way if you wanted:
count(distinct
case when Days = 1 then case when Service = 'Group' then 1 else "Date" end end
) as [1Day]
Depending on your indexing it's possible that introducing another column in the query would change the query plan. I suspect that probably isn't the case though.
If I am not wrong for '2Days' column service type 'Group' count should be '2' if our grouping based on 'Date' column, if so then try this:
SELECT
ID,
Service,
CASE WHEN MAX(t.days) = 4 THEN MAX(t.date) ELSE 0 END AS '4Days',
CASE WHEN MAX(t.days) = 3 THEN MAX(t.date) ELSE 0 END AS '3Days',
CASE WHEN MAX(t.days) = 2 THEN MAX(t.date) ELSE 0 END AS '2Days',
CASE WHEN MAX(t.days) = 1 THEN MAX(t.date) ELSE 0 END AS '1Day'
FROM table T1
OUTER APPLY (SELECT days,
COUNT(DISTINCT(date)) date
FROM Table WHERE days = t1.days GROUP BY days) t
GROUP BY id, service
ORDER BY ID
Based on your last edit, this is the most straight forward way I could think of to handle the query:
with cte as (
select id, service, days
from table t1
where service = 'Individual'
union all
select id, service, days
from table t1
where service = 'Group'
group by id, service, days, date
)
select id,
service,
count(case when days = 4 then 'X' end) as [4Days],
count(case when days = 3 then 'X' end) as [3Days],
count(case when days = 2 then 'X' end) as [2Days],
count(case when days = 1 then 'X' end) as [1Day]
from cte
group by id, service

Calculate Type of the member in a table (Self Join/Case When or any other possible way)

Here is the Table :
If OBJECT_ID ('tempdb..##SelfCount') Is not null
drop table #SelfCount
create table #SelfCount (CanID int , CanType int)
insert into #SelfCount (CanID, CanType)
values
(1,0),
(2,0),
(1,1),
(2,1),
(1,2),
(1,2),
(1,0)
CanID CanType
1 0
2 0
1 1
2 1
1 2
1 2
1 0
I'm Expecting the result to be like this
CanID Self Spouse Dependent
1 2 1 2
2 1 1 0/NULL --It doesn't matter if it's nUll or 0
I wrote this query
select CanID,
case
When CanType = 0 then count(CanType)
end as [self],
case
when CanType = 1 then count(CanType)
end as [Spouse],
Case
When CanType = 2 then count(CanType)
end as [Dependent]
from #SelfCount
Group by CanID, CanType
But the Result Set is like this :
CanID Self Spouse Dependent
1 2 NULL NULL
2 1 NULL NULL
1 NULL 1 NULL
2 NULL 1 NULL
1 NULL NULL 2
I've tried the Recursive method, If anyone could provide both Recursive as well as Set processing method, it'll be greatly appreciated.
By including the CanType in the group by clause, you're getting a separate result row per distinct value of CanType (and CanId, since it's also contained in the group by clause).
Instead, you should only have CanId in the group by clause, and apply different counts on case expressions:
SELECT CanID,
COUNT (CASE CanType WHEN 0 THEN 1 END) AS [Self],
COUNT (CASE CanType WHEN 1 THEN 1 END) AS [Spouse],
COUNT (CASE CanType WHEN 2 THEN 1 END) AS [Dependent],
FROM #SelfCount
GROUP BY CanID
May be this is what you need:
select CanID,
sum(case when CanType = 0 then 1 else 0 end) as [Self],
sum(case when CanType = 1 then 1 else 0 end) as [Spouse],
sum(case when CanType = 2 then 1 else 0 end) as [Dependent]
from #SelfCount
group by CanID
You can try with PIVOT:
select
CanID,
[0] as Self,
[1] as Spouse,
[2] as Dependent
from tab
pivot
(
count (CanType)
for CanType IN ([0], [1], [2])
) as pvt
Basically, it will group by all columns not declared inside the PIVOT clause (actually, just the CanID) and then create three aggregation COUNT columns, one FOR each CanType IN the list of values. If you need to count more values, just define them in the IN clause and in the SELECT clause.

Distinct counts per year

hello I am trying to count a person only once even if a person has two enrollments in the same year:
select DISTINCT Year, School,
count (case when [Graduate]= 1 AND [Dropout]= 0 THEN ID END) As 'passed',
count (case when [Graduate]= 0 AND [Dropout]= 1 THEN ID END) as 'dropped',
count (case when [Graduate]= 0 AND [Dropout]= 0 THEN ID END) as 'Continued'
from Table where ID = '10'
group by Year, School
my output is
Year school passed dropped continued
2012 School 0 0 1
2013 School 0 0 1
2014 School 0 0 2
continued is 2 for ID=1 because student enrolled twice. How do i get a distinct count in this case?
You are using DISTINCT wrong, it should be inside each COUNT:
SELECT [Year],
School,
COUNT(DISTINCT CASE WHEN [Graduate] = 1 AND [Dropout] = 0 THEN ID END) Passed,
COUNT(DISTINCT CASE WHEN [Graduate] = 0 AND [Dropout] = 1 THEN ID END) Dropped,
COUNT(DISTINCT CASE WHEN [Graduate] = 0 AND [Dropout] = 0 THEN ID END) Continued
FROM YourTable
WHERE ID = '10'
GROUP BY [Year],
School;

How to count the number of occurrence in a column in MSSQL

I have these tables:
Table A(Column1a, Column2a, Column3a);
Table B(Column1b);
Column1b values can be 0,1,2,3,4 or 5.
I want to count the number of 0,1,2,3 values in Column1b then store it in Column1a.
Column2a value will be the count of Column1b where the value is 1.
Column3a value will be the count of Column1b where the value is 2 or 3.
Thanks in advance guys!
INSERT INTO table_a (Column1a, Column2a, Column3a)
SELECT SUM(CASE WHEN Column1b IN (0,1,2,3) THEN 1 ELSE 0 END),
SUM(CASE WHEN Column1b = 1 THEN 1 ELSE 0 END),
SUM(CASE WHEN Column1b IN (2,3) THEN 1 ELSE 0 END)
FROM table_b

Resources