How to use multiple COUNT in SQL - mysql

In my table I have task, every task have state.
1 - planned
2 - executing
3 - finished
I want get count of all planned, executing and finished task.
I can write three queries like this:
SELECT COUNT(*) FROM `task` WHERE state = 1
SELECT COUNT(*) FROM `task` WHERE state = 2
SELECT COUNT(*) FROM `task` WHERE state = 3
So, my question is: It is possible (and how?) get this data in one query?
Thank you for any help.

another approach is to use group by, like this:
select state, count(*)
from task
group by state

you use SUM
select state,
sum(case when state = 1 then 1 else 0 end) state1count,
sum(case when state = 2 then 1 else 0 end) state2count,
sum(case when state = 3 then 1 else 0 end) state3count
from task

Related

sql query for count unique values and return single row

here is the structure of my table with data
empId, acitve
1,1
2,0
3,1
45,0
52,1
11,1
I want to know all members count [result is 6]
I want to know active member count (active=1) [result is 4]
I want to know non-active member count (active=0) [result is 2]
But all data should be return in a single row with appropriate column name.
I tried this but its result is not according the expectations:
SELECT Count(*) total, active as total
FROM it_staff_status
GROUP by active
Something like this
select Count(*) total,
sum(active=1) as activemem,
sum(active=0) as inactivemem
from yourtable
TRY THIS: User CASE to count active & inactive and you don't need group by here because all the columns are aggregated by using aggregate function:
SELECT Count(*) total,
SUM(CASE WHEN ACTIVE = 1 THEN 1 ELSE 0 END) as Active,
SUM(CASE WHEN ACTIVE = 0 THEN 1 ELSE 0 END) as InActive
FROM it_staff_status
Try this:
SELECT COUNT(*) as total,
SUM(CASE WHEN active = 1 THEN 1 END) as active_emp,
SUM(CASE WHEN active = 0 THEN 1 END) as inactive_emp
FROM it_staff_status

Several select count(*) in a single query

I have a mysql table(tbl_subscriptiondetails) like the above.Here the last column i.e
'test_status' could have possible values C,S & Y only.
Using a single query i would like to fetch data in the manner
as shown below
But the query that i'm using gives me undesired results.My query is
SELECT pkg_name,
(SELECT COUNT(*) FROM tbl_subscriptiondetails WHERE test_status='C' AND mem_id=3) AS completed,
(SELECT COUNT(*) FROM tbl_subscriptiondetails WHERE test_status='S' AND mem_id=3) AS started,
(SELECT COUNT(*) FROM tbl_subscriptiondetails WHERE test_status='Y' AND mem_id=3) AS remaining
FROM tbl_subscriptiondetails
WHERE mem_id=3
GROUP BY pkg_name
and the result is
Please advise what is wrong. Thanks in advance.
You are running a subquery for each count, instead of counting as part of the main query. Therefore, your filter conditions aren't behaving as you expect them to. You can change it like so, to do the conditional count:
SELECT pkg_name,
SUM( case when test_status='C' then 1 else 0 end) AS completed,
SUM( case when test_status='S' then 1 else 0 end) AS started,
SUM( case when test_status='Y' then 1 else 0 end) AS remaining
FROM tbl
WHERE mem_id = 3
GROUP BY pkg_name
Demo

Query to get different values depending on all column values

I have a table tasks with a status column The value of status can either be 0,1 or 2.
I need to implement the following logic:
If any value in status is 0 then the answer is 0.
If all values are 2 then the result is 2.
Otherwise the result is one.
Right now I'm doing this with 3 queries.
a) SELECT status FROM tasks
b) SELECT status FROM tasks WHERE status = 2;
c) SELECT status FROM tasks WHERE status = 0
So a) is for getting the total number of rows. Then I compare that to the number of rows given by b). If the match then the answer is 2. If they don't I do query c). If it is non-empty the answer is 0 otherwise the answer is 1.
Is there any way to write a single query for this? Or is there a better way of doing it?
You can do it using conditional aggregation:
SELECT CASE
WHEN s0 >= 1 THEN 0
WHEN sAll = s2 THEN 2
ELSE 1
END
FROM (
SELECT COUNT(*) AS sAll,
COUNT(CASE WHEN status = 0 THEN 1 END) AS s0,
COUNT(CASE WHEN status = 2 THEN 1 END) AS s2
FROM tasks ) t
The sub-query performs all counts required to apply your business logic. The outer query simply uses this info, to produce the required result.
It's a bit unclear from your description whether the first condition in the CASE takes precedence over the second. If not, then just switch the position of the two WHENs.
Try:
SELECT MIN(status) FROM tasks;
- since when all status values are 2, the minimum will be 2, when any value is 0 then the minimum will be 0 and otherwise the minimum wll be 1.
Use following
SELECT (case
when ((SELECT count(*) FROM tasks WHERE status = 0)>0) then 0
when ((SELECT count(*) FROM tasks WHERE status = 2)=(SELECT count(*) FROM tasks)) then 2
else 1 end) AS countOfStatus

Trying to get the count of items per day with SQL query

I have a db with several days of data and I want to get the count of each record with Status=0, Status=1...Status=8 for each day. I was to see something like.
DateAndTime State_0 State_1 State_2
2014-08-15 5 8 9
2014-08-16 2 5 6
2014-08-17 4 2 3
I was trying this:
SELECT DISTINCT DATEADD(dd,(DATEDIFF(dd,0,DateAndTime)),0) AS DateAndTime,
SUM( Case When State=0 Then 1 Else 0 End) AS State_0,
SUM( Case When State=1 Then 1 Else 0 End) AS State_1,
SUM( Case When State=2 Then 1 Else 0 End) AS State_2
FROM [DB_002].[dbo].[MyDb]
Group By DateAndTime
Order by DateAndTime
But it keeps adding rows for each state that I add. That is with 3 states I'm getting 4 rows for each date. Any suggestions on how to do this would be greatly appreciated.
You are grouping on the DateAndTime field, which contains also the time component. That makes each record practically unique, so there will be a single record in each group.
Group on the date only:
Group By DATEADD(dd,(DATEDIFF(dd,0,DateAndTime)),0)
Order by DATEADD(dd,(DATEDIFF(dd,0,DateAndTime)),0)
You are confused because you have changed a column and given it the same name as the original column. When you say group by DateAndTime, that is referring to the column in the table. Assuming this is SQL Server, I would write the query as something like this:
SELECT cast(d.DateAndTime as Date) as DateAndNoTime,
SUM(Case When d.State = 0 Then 1 Else 0 End) AS State_0,
SUM(Case When d.State = 1 Then 1 Else 0 End) AS State_1,
SUM(Case When d.State = 2 Then 1 Else 0 End) AS State_2
FROM [DB_002].[dbo].[MyDb] d
Group By cast(d.DateAndTime as Date)
Order by DateAndNoTime;
This changes the name of the alias in the select to avoid confusion. It uses the alias for column references, to also clarify the meaning of the query. And, it uses cast() instead of the old datedd/datediff trick.

same (sub)query multiple time in a mysql query

I have a mysql query like the following.
select new,processing,close
from
(select count(id) new from tickets where id_client in (_a_list_of_client_id) and status = new),
(select count(id) processing from tickets where id_client in (_a_list_of_client_id) and status = processing),
(select count(id) close from tickets where id_client in (_a_list_of_client_id) and status = close)
The following is not the exact query but a pseudo query
here _a_list_of_client_id is another query like following
select id_client from client where id_user = {some_id_given_as_parameter}
I just wondering is this the right approach to use same subquery multiple times in a query. Or is there any other way to do things like this.
Thanks in advance
M H Rasel
You can use sum with case and move the subquery to the where criteria:
select
sum(case when status = 'new' then 1 else 0 end) new,
sum(case when status = 'processing' then 1 else 0 end) processing,
sum(case when status = 'close' then 1 else 0 end) close
from tickets
where id_client in (_a_list_of_client_id)
There are a couple other ways to do this (using if for example or leaving out the case), but I think this is easy to read. I believe mysql will work with sum(status='new') for example.