I have a table as below .
Id Product1 Product2 Product3
1 1 null null
2 1 2 null
3 3 1 null
4 2 3 1
Now I would like to write a query to count the entries with Product 1.
In the above case it is 2 for Product1 , 1 for Product2 and 1 for Product 3
I came up with a query something like this.
select
Count(Product1) +
Count(Product2) +
Count(Product3)
from
Table
where Product1 = 1
But it gives me an inaccurate result.
Is there a way I can get the number of occurances for each product ?
Group By
Desired output would be something like this :
ProductID Product1Count Product2Count Product3Count
1 2 1 1
2 1 1 0
3 1 1 0
select Count(CASE WHEN Product1 = 1 THEN 1 END) +
Count(CASE WHEN Product2 = 1 THEN 1 END) +
Count(CASE WHEN Product3 = 1 THEN 1 END)
from Table1
where 1 IN (Product1, Product2, Product3)
SQLFIddle Demo
The reason for adding this line: where 1 IN (Product1, Product2, Product3) is to count only on the affected rows, thus making it more faster than running through all records.
Something like this would work:
SELECT
SUM(CASE WHEN Product1 = 1 THEN 1 ELSE 0 END)
+ SUM(CASE WHEN Product2 = 1 THEN 1 ELSE 0 END)
+ SUM(CASE WHEN Product3 = 1 THEN 1 ELSE 0 END)
FROM Table
Related
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#;
I have data like this: (table name: Activities)
ActivityId CreatedOn TypeId
1 2017-01-01 1
1 2017-01-02 1
1 2017-01-02 2
2 2017-01-01 3
Where Type is a lookup value: (table name: Types)
TypeId Name
1 Question
2 Answer
3 Comment
Basically it's an activity history table.
I want to turn the above tables into a grouped sum row for types, for each ActivityId, like this:
ActivityId QuestionCount AnswerCount CommentCount
1 2 1 0
2 0 0 1
I know the answer is probably pretty simple, but it's eluding me for some reason.
Any help? Thanks in advance.
A simple join and conditional aggregation should do the trick (I suspect you were over-thinking it)
Select ActivityID
,QuestionCount = sum(case when Name='Question' then 1 else 0 end)
,AnswerCount = sum(case when Name='Answer' then 1 else 0 end)
,CommentCount = sum(case when Name='Comment' then 1 else 0 end)
From Activities A
Join Types B on A.TypeId=B.TypeId
Group By ActivityId
Returns
ActivityID QuestionCount AnswerCount CommentCount
1 2 1 0
2 0 0 1
You could also do it without the Join... Just less readable
Select ActivityID
,QuestionCount = sum(case when TypeId=1 then 1 else 0 end)
,AnswerCount = sum(case when TypeId=2 then 1 else 0 end)
,CommentCount = sum(case when TypeId=3 then 1 else 0 end)
From #Activities A
Group By ActivityId
You could also try a PIVOT
Select ActivityID
,[1] as QuestionCount
,[2] as AnswerCount
,[3] as CommentCount
From (Select ActivityId,TypeID,1 as Cnt From #Activities) A
Pivot (count(Cnt) For TypeId in ([1],[2],[3]) ) p
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
I have table in following structure...
ReturnID SumbitID Status
1 1 1
1 NULL 2
2 2 3
3 3 1
3 3 1
I want this output.....
RetunrID TotalAttempt Success
1 2 1
2 1 0
3 2 2
Count Of ReturnID is TotalAttempt, when ReturnID = sumbitID and status =1 Then it count as success...
Thanks in Advance!
Something like this
SELECT
T.ReturnID
, COUNT(T.ReturnID) AS TotalAttempt
, SUM(CASE WHEN T.ReturnID = T.sumbitID AND T.Status = 1 THEN 1 ELSE 0 END) AS Status
FROM dbo.MyTable T
group by T.ReturnID
Check this:
SELECT T.ReturnID , COUNT(T.ReturnID) AS TotalAttempt , SUM(CASE WHEN T.ReturnID = T.sumbitID AND T.Statusa = 1 THEN 1 ELSE 0 END) AS Status FROM #table T GROUP BY T.ReturnID
I have a table with data named Product
ProductID ProductName
1 ABC
2 PQR
3 XYZ
4 HJK
5 LKJ
6 MNB
... ....
with many more product in it. What I want is result like this on Select query:
RowNo ProductID ProductName
1 1 ABC
1 2 PQR
2 3 XYZ
2 4 HJK
1 5 LKJ
1 6 MNB
2 7 klj
2 8 hjg
then 1,1, 2,2 1,1 for the number of records in the table. Is it possible, and if so how can I do that?
This works for your sample data which assumes ProductID is contiguous:
SELECT
CASE WHEN ProductID % 4 = 0 OR (ProductID+1) % 4 = 0 THEN 2 ELSE 1 END,
ProductID,
ProductName
FROM
Product
Now, guessing that you mean in resultset which may have gaps in ProductID
SELECT
CASE WHEN ContiguousProductID % 4 = 0 OR (ContiguousProductID+1) % 4 = 0 THEN 2 ELSE 1 END,
--ContiguousProductID,
--CASE WHEN ProductID % 4 = 0 OR (ProductID+1) % 4 = 0 THEN 2 ELSE 1 END,
ProductID,
ProductName
FROM
(
SELECT
ROW_NUMBER() OVER (ORDER BY ProductID) AS ContiguousProductID,
ProductName, ProductID
FROM
dbo.Product
) P2