I am querying on table below.
SELECT [RiskUniqueIdentificationNo]
,Count(*) AS TotalNoOfTasks
,[Status]
FROM [dbo].[Tasks]
GROUP BY [RiskUniqueIdentificationNo]
,[Status]
and here is my result set
but problem is that i want to get result for each [RiskUniqueIdentificationNo] in following way
| RiskUniqueIdentificationNo | | TotalNoOfTasks | | InProgressTask | | ClosedTask |
------------ ------------ ------------ ------------------------- ------------------
| 1 | | 3 | | 2 | | 1|
i have tried to do some thing like this
SELECT [RiskUniqueIdentificationNo]
,Count(*) AS TotalNoOfTasks
,CASE
WHEN [Status] = 'Closed'
THEN COUNT([Status])
ELSE 0
END AS ClosedTasks
,CASE
WHEN [Status] != 'Closed'
AND [EndDate] < GETDATE()
THEN COUNT([Status])
ELSE 0
END AS OverdueTasks
FROM [dbo].[Tasks]
GROUP BY [RiskUniqueIdentificationNo]
,[Status]
but can't succeeded. I need help that how can i accomplish this.
Remove status from GROUP BY and do a COUNT using CASE.
SELECT [RiskUniqueIdentificationNo],
COUNT(1) AS TotalNoOfTasks,
COUNT(CASE WHEN [Status]<> 'Closed' THEN 1 END) AS InProgressTask,
COUNT(CASE WHEN [Status]= 'Closed' THEN 1 END) AS ClosedTask
FROM [dbo].[Tasks]
GROUP BY [RiskUniqueIdentificationNo]
Move to conditional aggregation as below
Select [RiskUniqueIdentificationNo],
Count(*) as TotalNoOfTasks,
sum(case when [Status] = 'In progress' then 1 else 0 end) [InProgressTask],
sum(case when [Status] = 'Closed' then 1 else 0 end) [ClosedTask]
from [dbo].[Tasks]
group by [RiskUniqueIdentificationNo]
Related
I have the following SQL query:
SELECT
modal_text,
COUNT(CASE WHEN ab_group = "control" THEN 1 ELSE 0 END)
FROM
onboarding_modals
GROUP BY
1
ORDER BY
1;
This doesn't work as expected (it will count more than expected), but when I remove the ELSE 0 in aggregate function, it works as expected:
SELECT
modal_text, COUNT(CASE WHEN ab_group = "control" THEN 1 END)
FROM
onboarding_modals
GROUP BY
1
ORDER BY
1;
Could someone explain me why having the ELSE 0 will make it count more data than it should be?
*It will also work if I use ELSE NULL
Because a COUNT(SomeColumn) doesn't count the NULL's in a column.
COUNT(1) or COUNT(*) count the rows.
And so does a COUNT(CASE WHEN x=1 THEN 1 ELSE 0 END)
This has no NULL's to ignore, because it's either 1 or 0.
But a CASE WHEN x=1 THEN 1 END
is just the implicit shorter syntax for
CASE WHEN x=1 THEN 1 ELSE NULL END
So it's normal to COUNT without the ELSE.
COUNT(DISTINCT CASE WHEN x=1 THEN t.ID END)
If you do want to use an ELSE, then do it with a SUM
SUM(CASE WHEN x=1 THEN 1 ELSE 0 END)
Use SUM() instead of COUNT(), as in:
SELECT
modal_text,
SUM(CASE WHEN ab_group = "control" THEN 1 ELSE 0 END)
FROM
onboarding_modals
GROUP BY
1
ORDER BY
1;
Could someone explain me why having the ELSE 0 will make it count more data than it should be?
Becasue COUNT(CASE WHEN ab_group = "control" THEN 1 ELSE 0 END) is different to COUNT(CASE WHEN ab_group = "control" THEN 1 END) let's see a sample below
we can see there will be count when we use count(1) or count(0) except count(null) count function will not be count when the value is null
Query 1:
SELECT COUNT(1)
| COUNT(1) |
|----------|
| 1 |
SELECT COUNT(0)
| COUNT(0) |
|----------|
| 1 |
SELECT COUNT(NULL)
| COUNT(NULL) |
|-------------|
| 0 |
Query 2:
SELECT SUM(1)
| SUM(1) |
|--------|
| 1 |
SELECT SUM(0)
| SUM(0) |
|--------|
| 0 |
SELECT SUM(NULL)
| SUM(NULL) |
|-----------|
| (null) |
Results:
Extremely simple case - I can't calculate properly the number of months for below table - the expected number is 2, not 3 - what is interesting the "valueagg" is calculated properly with same condition!
INSERT INTO ForgeRock
([productName], [description], [month], [value] )
VALUES
('OpenIDM', 'Y',1,33.2),
('OpenIDM', 'Y',2, 12.1),
('OpenIDM', 'Y',3, 1.1)
;
TEST
SELECT
productName,
description,
sum(CASE WHEN [MONTH] between 1 and 2 then [VALUE] else 0 end) valueagg --works
,count(CASE WHEN [MONTH] between 1 and 2 then [MONTH] else 0 end) month_count --doesn't work
,count(CASE WHEN [MONTH] between 1 and 2 then 1 else 0 end) month_count2 --doesn't work
FROM
ForgeRock
group by productName,
description
RESULT
| productName | description | valueagg | month_count | month_count2 |
|-------------|-------------|--------------------|-------------|--------------|
| OpenIDM | Y | 45.300000000000004 | 3 | 3 |
http://sqlfiddle.com/#!18/14603/3/0
You are using count() with else. count() counts the number of non-NULL values and -- 0 is just as "not NULL" as any other value.
Use sum() instead:
SELECT productName, description,
SUM(CASE WHEN [MONTH] between 1 and 2 then [VALUE] else 0 end) as valueagg --works
SUM(CASE WHEN [MONTH] between 1 and 2 then [MONTH] else 0 end) as month_count --doesn't work
SUM(CASE WHEN [MONTH] between 1 and 2 then 1 else 0 end) month_count2 --doesn't work
FROM ForgeRock
GROUP BY productName, description
Or remove the ELSE from the COUNT().
Remove the ELSE part of the CASE expressions:
SELECT
productName,
description,
sum(CASE WHEN [MONTH] between 1 and 2 then [VALUE] else 0 end) valueagg
,count(CASE WHEN [MONTH] between 1 and 2 then [MONTH] end) month_count
FROM
ForgeRock
group by productName,
description
or replace with SUM() like this:
SELECT
productName,
description,
sum(CASE WHEN [MONTH] between 1 and 2 then [VALUE] else 0 end) valueagg
,sum(CASE WHEN [MONTH] between 1 and 2 then 1 else 0 end) month_count
FROM
ForgeRock
group by productName,
description
I'm currently trying to figure out the best way to do a conditional count as an alias in DB2 for Iseries. The below values represent job statuses where a job can be created, completed and cancelled so any one job will possibly have multiple status codes attached to it.
However, for my final value, I'm trying to get a count of jobs that only have the created status so that I can show how many are still open jobs. Basically looking for cases where the count for the created case = 1, but the below fails at the '='
SELECT
COUNT(CASE A1.JOB WHEN = 'CREATED' THEN 1 END) AS CREATED,
COUNT(CASE A1.JOB WHEN = 'CANCELLED' THEN 1 END) AS CANCELLED,
COUNT(CASE WHEN A1.JOB 'CREATED' = 1 then 1 END) AS OPEN
FROM SCHEMA.TABLE A1;
sample data and results:
Job ID | Status_code
-------------------------
123 'CREATED'
123 'COMPLETED'
521 'CREATED'
521 'CANCELLED'
645 'CREATED'
Results:
JOB | CREATED | CANCELLED | OPEN
-------------------------------------------
123 1 0 0
521 1 1 0
645 1 0 1
Assuming that the only "close" status is 'CANCELLED', you can use not exists like this:
select count(*)
from schema.table t
where t.status_code = 'CREATED' and
not exists (select 1
from schema.table t2
where t2.job = t.job and
t2.status_code in ('CANCELLED', 'COMPLETED', 'DELETED')
);
If you want multiple counts, then filtering like this does not work. So aggregate by job first:
select sum(is_created) as num_created,
sum(is_cancelled) as num_cancelled,
sum(is_created * (1 - is_cancelled) * (1 - is_completed) * (1 - is_deleted)) as open
from (select job,
max(case when status_code = 'CREATED' then 1 else 0 end) as is_created,
max(case when status_code = 'CANCELLED' then 1 else 0 end) as is_cancelled,
max(case when status_code = 'COMPLETED' then 1 else 0 end) as is_completed,
max(case when status_code = 'DELETED' then 1 else 0 end) as is_deleted
from t
group by job
) j
The following returns the result you need:
WITH TAB (Job_ID, JOB) AS
(
VALUES
(123, 'CREATED')
, (123, 'COMPLETED')
, (521, 'CREATED')
, (521, 'CANCELLED')
, (645, 'CREATED')
)
SELECT
Job_ID
, COUNT(CASE A1.JOB WHEN 'CREATED' THEN 1 END) AS CREATED
, COUNT(CASE A1.JOB WHEN 'CANCELLED' THEN 1 END) AS CANCELLED
, CASE
WHEN NULLIF(COUNT(1), 0) = COUNT(CASE A1.JOB WHEN 'CREATED' then 1 END)
THEN 1
ELSE 0
END AS OPEN
FROM TAB A1
GROUP BY JOB_ID;
With conditional aggregation:
SELECT
JobID,
MAX(CASE Status_code WHEN 'CREATED' THEN 1 ELSE 0 END) AS CREATED,
MAX(CASE Status_code WHEN 'CANCELLED' THEN 1 ELSE 0 END) AS CANCELLED,
MIN(CASE WHEN Status_code <> 'CREATED' THEN 0 ELSE 1 END) AS OPEN
FROM tablename
GROUP BY JobID
See the demo.
Results:
> JobID | CREATED | CANCELLED | OPEN
> ----: | ------: | --------: | ---:
> 123 | 1 | 0 | 0
> 521 | 1 | 1 | 0
> 645 | 1 | 0 | 1
Assuming valid close status is either "COMPLETED" or "CANCELLED", you can try following SQL.
SELECT
A1.JobID,
sum(CASE WHEN A1.Status_code = 'CREATED' THEN 1 ELSE 0 END) AS CREATED,
sum(CASE WHEN A1.Status_code = 'CANCELLED' THEN 1 ELSE 0 END) AS CANCELLED,
(
SUM(CASE WHEN A1.Status_code = 'CREATED' THEN 1 ELSE 0 END)
- sum(CASE WHEN A1.Status_code = 'CANCELLED' THEN 1 ELSE 0 END)
- sum(CASE WHEN A1.Status_code = 'COMPLETED' THEN 1 ELSE 0 END)
) AS OPEN
FROM SCHEMA.TABLE A1
GROUP BY A1.JobID
I have a SQL table that contains three columns:
userId
userName
item
and I created this SQL query which will count all the items types of one user:
select
count(ItemID) as 'count of all items types',
userId,
userName
from
userTable
where
ItemID in (2, 3, 4)
and userId = 1
group by
userId, userName
The result will be like this:
+--------+----------+--------------------------+
| userId | userName | count of all items types |
+--------+----------+--------------------------+
| 1 | kim | 25 |
and I am looking for a way to separate the counting of itemes types, so the result should be like this:
+--------+----------+----------------+----------------+-----------------+
| userId | userName | count of item1 | count of item2 | count of item3 |
+--------+----------+----------------+----------------+-----------------+
| 1 | kim | 10 | 10 | 5 |
SELECT
userID,
userName,
SUM(CASE WHEN ItemID = 2 THEN 1 ELSE 0 END) AS count_of_item1,
SUM(CASE WHEN ItemID = 3 THEN 1 ELSE 0 END) AS count_of_item2,
SUM(CASE WHEN ItemID = 4 THEN 1 ELSE 0 END) AS count_of_item3
FROM
My_Table
GROUP BY
userID,
userName
This is called conditional aggregation. Use CASE for this.
With COUNT:
select
count(case when ItemID = 1 then 1 end) as count_item1,
count(case when ItemID = 2 then 1 end) as count_item2,
count(case when ItemID = 3 then 1 end) as count_item3
...
(then 1 could also be anything else except null, e.g. then 'count me'. This works because COUNT counts non-null values and when omitting the ELSE in CASE WHEN you get null. You could also explicitly add else null.)
Or with SUM:
select
sum(case when ItemID = 1 then 1 else 0 end) as count_item1,
sum(case when ItemID = 2 then 1 else 0 end) as count_item2,
sum(case when ItemID = 3 then 1 else 0 end) as count_item3
...
This is how you would do it :
select userId,
username,
SUM(CASE WHEN ItemID = '2' THEN 1 ELSE 0 END) AS Item2-Cnt,
SUM(CASE WHEN ItemID = '3' THEN 1 ELSE 0 END) AS Item3-Cnt,
SUM(CASE WHEN ItemID = '4' THEN 1 ELSE 0 END) AS Item4-Cnt
FROM userTable
GROUP BY userID, userName
I've searched for an answer on this but can't find quite how to get this distinct recordset based on a condition. I have a table with the following sample data:
+---------+-------------+
| Branch | Task Status |
+---------+-------------+
| Account | Completed |
| HR | Completed |
| Account | Completed |
| HR | Not Define |
| Account | Uncompleted |
| Account | Not Define |
| Account | Completed |
| HR | Uncompleted |
| HR | Uncompleted |
| HR | Completed |
| HR | Not Define |
+---------+-------------+
I'd like to create a query that shows the count of total task and also want total of Task Status wise numbers of tasks, e.g.
Branch Total Task Completed Uncompleted Not Define
Account 5 3 1 1
Admin 6 2 2 2
SELECT branch,
COUNT(*),
SUM(CASE status WHEN 'completed' THEN 1 END) AS completed,
SUM(CASE status WHEN 'uncompleted' THEN 1 END) AS uncompleted,
SUM(CASE status WHEN 'not define' THEN 1 END) AS not_define
FROM task
GROUP BY
branch
SELECT Branch
, COUNT(1) as Total
, COUNT(CASE WHEN TaskStatus = 'Completed' THEN 1 ELSE 0 END) AS Completed
, COUNT(CASE WHEN TaskStatus = 'Uncompleted' THEN 1 ELSE 0 END) AS Uncompleted
, COUNT(CASE WHEN TaskStatus = 'Not Define' THEN 1 ELSE 0 END) AS NotDefine
FROM Table
GROUP BY Branch
SELECT branch,
COUNT(*),
COUNT(CASE taskstatus WHEN 'Completed' THEN 1 END),
COUNT(CASE taskstatus WHEN 'Uncompleted' THEN 1 END),
COUNT(CASE taskstatus WHEN 'Not Define' THEN 1 END)
FROM YourTable
GROUP BY branch;
Try this
SELECT * FROM (SELECT
ROW_NUMBER() OVER(PARTITION BY Branch ORDER BY [Task Status]) AS No,
Branch,
sum (CASE WHEN [Task Status] = 'Completed' THEN 1 ELSE 0 END ) OVER (PARTITION BY Branch) AS [Completed],
sum (CASE WHEN [Task Status] = 'Not Define' THEN 1 ELSE 0 END ) OVER (PARTITION BY Branch) AS [Not Define],
sum (CASE WHEN [Task Status] = 'Uncompleted' THEN 1 ELSE 0 END ) OVER (PARTITION BY Branch) AS [Uncompleted]
FROM task ) AS T1 WHERE No = 1
or
SELECT * FROM (SELECT
ROW_NUMBER() OVER(PARTITION BY Branch ORDER BY [Task Status]) AS No,
Branch,
count (CASE WHEN [Task Status] = 'Completed' THEN 1 ELSE 0 END ) OVER (PARTITION BY Branch) AS [Completed],
count (CASE WHEN [Task Status] = 'Not Define' THEN 1 ELSE 0 END ) OVER (PARTITION BY Branch) AS [Not Define],
count (CASE WHEN [Task Status] = 'Uncompleted' THEN 1 ELSE 0 END ) OVER (PARTITION BY Branch) AS [Uncompleted]
FROM task ) AS T1 WHERE No = 1
In SQL Server2005+ you can use PIVOT operator
SELECT *
FROM (
SELECT *, COUNT(*) OVER(PARTITION BY Branch) AS TotalTask
FROM dbo.task
) p
PIVOT
(
COUNT(p.Task) FOR p.Task IN ([Completed], [Uncompleted], [Not Define])
) x
Demo on SQLFiddle