I have a select like this:
SELECT
[Status] AS Requested
,[Status] AS [Sent]
,[Status] AS Finished
FROM Store.[Order]
Status is an int value and I want Count all Status
Count value = 1 and display as a Requested.
Count value = 2 and display as Sent.
Count value = 3 and display as Finished.
How can I achieve it? Regards
Use case expression to count status based on value (1,2,3)
SELECT
SUM(CASE WHEN [Status] = 1 THEN 1 ELSE 0 END) AS Requested,
SUM(CASE WHEN [Status] = 2 THEN 1 ELSE 0 END) AS Sent,
SUM(CASE WHEN [Status] = 3 THEN 1 ELSE 0 END) AS Finished
FROM Store.[Order]
Related
I have a table with Course-Participants, Course_Id and Status.
I want the number of records from Course-Participants to stay the same. But from the combination of Course_Id and Status it should show a total.
It should look like this:
And this is my attempt:
SELECT
[Course_Id]
,Sum(case when Course_ID is not null and Status = 0 THEN 1 else 0 end) as Sum_Status_A
,Sum(case when Course_ID is not null and Status = 1 THEN 1 else 0 end) as Sum_Status_B
,Sum(case when Course_ID is not null and Status = 2 THEN 1 else 0 end) as Sum_Status_C
FROM CourseParticipant
group by course_id
because of the group by statement, I cannot include the course participant in the query. As a result, I cannot output the desired number of data records.
Also select participant_id and add it the the group by:
SELECT
Course_Id,
Participant_id,
Sum(case when Course_ID is not null and Status = 0 THEN 1 else 0 end) as Sum_Status_A,
Sum(case when Course_ID is not null and Status = 1 THEN 1 else 0 end) as Sum_Status_B,
Sum(case when Course_ID is not null and Status = 2 THEN 1 else 0 end) as Sum_Status_C
FROM CourseParticipant
group by course_id, participant_id
I am working on a project in SQL Server with diagnosis codes and a patient can have up to 4 codes but not necessarily more than 1 and a patient cannot repeat a code more than once. However, codes can occur in any order. My goal is to be able to count how many times a Diagnosis code appears in total, as well as how often it appears in a set position.
My data currently resembles the following:
PtKey
Order #
Order Date
Diagnosis1
Diagnosis2
Diagnosis3
Diagnosis 4
345
1527
7/12/20
J44.9
R26.2
NULL
NULL
367
1679
7/12/20
R26.2
H27.2
G47.34
NULL
325
1700
7/12/20
G47.34
NULL
NULL
NULL
327
1710
7/12/20
I26.2
J44.9
G47.34
NULL
I would think the best approach would be to create a dummy column here that would match up the diagnosis by position. For example, Diagnosis 1 with A, and Diagnosis 2 with B, etc.
My current plan is to rollup the diagnosis using an unpivot:
UNPIVOT ( Diag for ColumnALL IN (Diagnosis1, Diagnosis2, Diagnosis3, Diagnosis4)) as unpvt
However, this still doesn’t provide a way to count the diagnoses by position on a sales order.
I want it to look like this:
Diagnosis
Total Count
Diag1 Count
Diag2 Count
Diag3 Count
Diag4 Count
J44.9
2
1
1
0
0
R26.2
1
1
0
0
0
H27.2
1
0
1
0
0
I26.2
1
1
0
0
0
G47.34
3
1
0
2
0
You can unpivot using apply and aggregate:
select v.diagnosis, count(*) as cnt,
sum(case when pos = 1 then 1 else 0 end) as pos_1,
sum(case when pos = 2 then 1 else 0 end) as pos_2,
sum(case when pos = 3 then 1 else 0 end) as pos_3,
sum(case when pos = 4 then 1 else 0 end) as pos_4
from data d cross apply
(values (diagnosis1, 1),
(diagnosis2, 2),
(diagnosis3, 3),
(diagnosis4, 4)
) v(diagnosis, pos)
where diagnosis is not null;
Another way is to use UNPIVOT to transform the columns into groupable entities:
SELECT Diagnosis, [Total Count] = COUNT(*),
[Diag1 Count] = SUM(CASE WHEN DiagGroup = N'Diagnosis1' THEN 1 ELSE 0 END),
[Diag2 Count] = SUM(CASE WHEN DiagGroup = N'Diagnosis2' THEN 1 ELSE 0 END),
[Diag3 Count] = SUM(CASE WHEN DiagGroup = N'Diagnosis3' THEN 1 ELSE 0 END),
[Diag4 Count] = SUM(CASE WHEN DiagGroup = N'Diagnosis4' THEN 1 ELSE 0 END)
FROM
(
SELECT * FROM #x UNPIVOT (Diagnosis FOR DiagGroup IN
([Diagnosis1],[Diagnosis2],[Diagnosis3],[Diagnosis4])) up
) AS x GROUP BY Diagnosis;
Example db<>fiddle
You can also manually unpivot via UNION before doing the conditional aggregation:
SELECT Diagnosis, COUNT(*) As Total Count
, SUM(CASE WHEN Position = 1 THEN 1 ELSE 0 END) As [Diag1 Count]
, SUM(CASE WHEN Position = 2 THEN 1 ELSE 0 END) As [Diag2 Count]
, SUM(CASE WHEN Position = 3 THEN 1 ELSE 0 END) As [Diag3 Count]
, SUM(CASE WHEN Position = 4 THEN 1 ELSE 0 END) As [Diag4 Count]
FROM
(
SELECT PtKey, Diagnosis1 As Diagnosis, 1 As Position
FROM [MyTable]
UNION ALL
SELECT PtKey, Diagnosis2 As Diagnosis, 2 As Position
FROM [MyTable]
WHERE Diagnosis2 IS NOT NULL
UNION ALL
SELECT PtKey, Diagnosis3 As Diagnosis, 3 As Position
FROM [MyTable]
WHERE Diagnosis3 IS NOT NULL
UNION ALL
SELECT PtKey, Diagnosis4 As Diagnosis, 4 As Position
FROM [MyTable]
WHERE Diagnosis4 IS NOT NULL
) d
GROUP BY Diagnosis
Borrowing Aaron's fiddle, to avoid needing to rebuild the schema from scratch, and we get this:
https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=d1f7f525e175f0f066dd1749c49cc46d
I have a table in the database shown as shown below:
Status
Email
Count
Assigned
admin1#admin1.com
1
Completed
admin1#admin1.com
1
InProgress
admin1#admin1.com
2
Assigned
admin2#admin2.com
5
The possible values in the Status column are Assigned, InProgress and Completed.
I want a result to be displayed like this:
Email
Assigned
InProgress
Completed
admin1#admin1.com
1
2
1
admin2#admin2.com
5
0
0
You can use conditional aggregation:
select email,
sum(case when status = 'Assigned' then count else 0 end) as assigned,
sum(case when status = 'InProgress' then count else 0 end) as InProgress,
sum(case when status = 'Completed' then count else 0 end) as Completed
from t
group by email;
How to total count?
SELECT
COUNT(CASE WHEN SHP.id = 1 then 1 ELSE NULL END) as "New",
COUNT(CASE WHEN SHP.id = 2 then 5 ELSE NULL END) as "Accepted"
from SHP
RESULT:
NEW Accepted
1 5
But I need a total count
result: 6
I'd do something like this;
SELECT
COUNT(CASE WHEN id = 1 THEN 1 END) as New,
COUNT(CASE WHEN id = 2 THEN 5 END) as Accepted,
COUNT(CASE WHEN id = 1 THEN 1
WHEN id = 2 THEN 5 END) as Total
FROM SHP
This is exactly what the CASE statement should be used for, the logic is very simple. This will avoid having to perform multiple calculations on the same fields.
As a note, the value in your THEN statement isn't used in this instance at all, it's just doing a COUNT of the number rather than performing a SUM. I've also removed the ELSE NULL because this is what the CASE will do by default anyway.
If your intention was to SUM the values then do this;
SELECT
SUM(CASE WHEN id = 1 THEN 1 END) as New,
SUM(CASE WHEN id = 2 THEN 5 END) as Accepted,
SUM(CASE WHEN id = 1 THEN 1
WHEN id = 2 THEN 5 END) as Total
FROM SHP
Example
Assuming you have only two values in your database, 1 and 2, we can create test data like this;
CREATE TABLE #SHP (id int)
INSERT INTO #SHP (id)
VALUES (1),(2)
And use this query;
SELECT
SUM(CASE WHEN id = 1 then 1 END) as New,
SUM(CASE WHEN id = 2 then 5 END) as Accepted,
SUM(CASE WHEN id = 1 THEN 1
WHEN id = 2 THEN 5 END) as Total
FROM #SHP
Gives this result;
New Accepted Total
1 5 6
Try this:
SELECT
COUNT(CASE WHEN SHP.id = 1 then 1 ELSE NULL END) +
COUNT(CASE WHEN SHP.id = 2 then 5 ELSE NULL END) as "Total"
from SHP
You could wrap your query into a subquery and do something like this:
SELECT SUM(New) as New, Sum(Accepted) as Accepted, Sum(New + Accepted) as Total FROM
(SELECT
COUNT(CASE WHEN SHP.id = 1 then 1 ELSE NULL END) as "New",
COUNT(CASE WHEN SHP.id = 2 then 5 ELSE NULL END) as "Accepted"
from SHP) as SubQuery
That's if you don't want to duplicate doing the counts and just adding the two together.
try this
with s1 as(
SELECT
COUNT(CASE WHEN SHP.id = 1 then 1 ELSE 0 END) as "New"
from SHP
),s2 as
(
SELECT
COUNT(CASE WHEN SHP.id = 2 then 5 ELSE 0 END) as "Accepted"
from SHP
)
select sum("New"+ "Accepted") from s1,s2
I have the following query which is supposed to return the number of passed and failed activities.
I'm stock at calculating the percentage ratio between the failed and passed activities for each row, as you can see right now I am returning 0.
any help is much appreciated.
query:
WITH CTE
AS(
select activityid,
SUM(CASE WHEN success = 1 THEN 1 ELSE 0 END) AS Pass,
SUM(CASE WHEN success = 0 THEN 1 ELSE 0 END) AS Fail
from mytable
group by activityid
)
select activityid, pass, fail,
0 as passPercentage, 0 failPercentage
from cte
resultset:
activityid pass fail passPercentage failPercentage
1 26 22 0 0
2 23 29 0 0
Try this:
WITH CTE
AS(
select activityid,
SUM(CASE WHEN success = 1 THEN 1 ELSE 0 END) AS Pass,
SUM(CASE WHEN success = 0 THEN 1 ELSE 0 END) AS Fail
from mytable
group by activityid
)
select activityid, pass, fail,
pass*100.0/(pass + fail) as passPercentage,
fail*100.0/(pass + fail) as failPercentage
from cte
UPDATE
In case f you have empty activities.
WITH CTE
AS(
select activityid,
SUM(CASE WHEN success = 1 THEN 1 ELSE 0 END) AS Pass,
SUM(CASE WHEN success = 0 THEN 1 ELSE 0 END) AS Fail
from mytable
group by activityid
)
select activityid, pass, fail,
CASE WHEN pass + fail = 0 THEN 0 ELSE pass*100.0/(pass + fail) END as passPercentage,
CASE WHEN pass + fail = 0 THEN 0 ELSE fail*100.0/(pass + fail) END as failPercentage
from cte