How to get the count of specific rows as columns - sql

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;

Related

Sum a column into two different columns based on another column's value

What I need is only a list of the items in "Storage", but the resulting set should include the sum of that item's quantity in both the storage and active locations.
Here's a dataset example:
ID
Item
Location
Qty
1
ItemA
Storage
4
2
ItemA
Active
9
3
ItemB
Storage
3
4
ItemB
Storage
2
5
ItemA
Active
1
6
ItemC
Boxed
3
7
ItemD
Active
1
8
ItemD
Storage
1
The result would look like this:
Item
Storage
Active
ItemA
4
10
ItemB
5
0
ItemD
1
1
Note that ItemC should not be included because it is not in a valid location.
What I have tried so far is:
SELECT
ITEMDESC.A,
SUM(CASE WHEN LOCATION.A='Storage' THEN QTY.A ELSE 0 END),
SUM(CASE WHEN LOCATION.B='Active' THEN QTY.B ELSE 0 END)
FROM
ITEMS A, ITEMS B
INNER JOIN
ITEMDESC.A = ITEMDESC.B
WHERE
GROUP BY
ITEMDESC.A
but this returns ALL items listed. When I add something like "WHERE Location.B = 'Storage'" then it only sums the items in the storage and all the active location items are 0.
Use a WHERE clause to only look at the locations in question:
select
item,
sum(case when location = 'Storage' then qty else 0 end) as storage,
sum(case when location = 'Active' then qty else 0 end) as active
from items
where location in ('Storage', 'Active')
group by item
order by item;
Update
You have changed the desired output in your request and only want items that are in 'Storage'. For this, just add a HAVING clause, e.g.:
select
item,
sum(case when location = 'Storage' then qty else 0 end) as storage,
sum(case when location = 'Active' then qty else 0 end) as active
from items
where location in ('Storage', 'Active')
group by item
having sum(case when location = 'Storage' then qty else 0 end) > 0
order by item;
This should give you the desired results. The other answers are including values not in 'storage'
select
item,
sum(case when location = 'Active' then qty else 0 end) as active_qty,
sum(case when location = 'Storage' then qty else 0 end) as storage_qty
from *table*
where item in (select item from *table* where location = 'Storage')
group by item
order by item;
Select item,
SUM(Case When Location = 'Storage' THEN Qty else 0 END) AS Storage,
SUM(Case When Location = 'Active' THEN Qty else 0 END) AS Active
from table1
where location in ('Storage','Active')
GROUP BY Item
http://sqlfiddle.com/#!9/7339b9a/8
You could use the WHERE clause in a subquery to identify items of interest and then JOIN to filter the rows prior to aggregation
SELECT
A.ITEMDESC,
SUM(CASE WHEN A.LOCATION='Storage' THEN A.QTY ELSE 0 END),
SUM(CASE WHEN A.LOCATION='Active' THEN A.QTY ELSE 0 END)
FROM
ITEMS A
INNER JOIN
(SELECT DISTINCT ITEMDESC FROM ITEMS WHERE LOCATION='Storage') B
ON
A. ITEMDESC = B.ITEMDESC
GROUP BY
A.ITEMDESC
Or you could filter the rows after aggregation with a HAVING clause
SELECT
ITEMDESC,
SUM(CASE WHEN LOCATION='Storage' THEN QTY ELSE 0 END),
SUM(CASE WHEN LOCATION='Active' THEN QTY ELSE 0 END)
FROM
ITEMS
GROUP BY
ITEMDESC
HAVING
MAX(CASE WHEN LOCATION='Storage' THEN 1 ELSE 0 END) > 0

Keep the number of data records but the sum of two other Variables should be calculated

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

SQL return only specific rows with specific status

I have this table below with two columns
Order_No Order_Status
A Receiving
A Active
A Retired
A Ordering
B Receiving
B Ordering
C Active
C Retired
D Receiving
E Ordering
I would like to get Order_no B, D and E records because it's order status is ( Receiving/Ordering ). It should filter out A and C because both have Active and Retired status.
I tried the below query but it's not showing up the results.
select ORDER_NUMBER
from table ror
where ror.use_Status
Order_Status not in ('Active', 'Retired')
and Order_Status in ('Receiving', 'Ordering').
Could anyone please tell me what wrong I am doing or I'm missing any joins?
You can use group by and having:
select order_no
from mytable
group by order_no
having max(case when status = 'Receiving' then 1 else 0 end) = 1
and max(case when status = 'Ordering' then 1 else 0 end) = 1
and max(case when status not in ('Receiving', 'Ordering') then 1 else 0 end) = 0
This phrases as: get all orders that have both "Receiving" and "Ordering" statuses, and no other status.
If a given order cannot have the same status twice, then the having can be simplified a little:
having sum(case when status in ('Receiving', 'Ordering') then 1 else 0 end) = 2
and sum(case when status not in ('Receiving', 'Ordering') then 1 else 0 end) = 0
Edit - if you want order that have either "Receiving" and "Ordering" statuses (not necessarily both), then a single condition is sufficient:
having max(case when status not in ('Receiving', 'Ordering') then 1 else 0 end) = 0

Select count of same column with different value

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]

SQL: Comparing count of 2 fields with specific value

I have 2 tables, one (Jobs) contains the list of the jobs and second contains the details of the records in each job.
Jobs
JobID Count
A 2
B 3
Records
JobID RecordID ToBeProcessed IsProcessed
A A1 1 1
A A2 1 1
B B1 1 1
B B2 1 0
B B3 1 0
How would I be able to create a query that would list all the jobs that have the count of ToBeProcessed which has a value of 1 is equal to the count of isProcessed that has a value of 1? Thanks in advance. Any help is greatly appreciated.
Start with the calculation of the number of items with ToBeProcessed set to 1 or IsProcessed set to one:
SELECT
JobID
, SUM(CASE WHEN ToBeProcessed=1 THEN 1 ELSE 0 END) ToBeProcessedIsOne
, SUM(CASE WHEN IsProcessed=1 THEN 1 ELSE 0 END) IsProcessedIsOne
FROM Records
GROUP BY JobID
This gives you all counts, not only ones where ToBeProcessedIsOne is equal to IsProcessedIsOne. To make sure that you get only the records where the two are the same, use either a HAVING clause, or a nested subquery:
-- HAVING clause
SELECT
JobID
, SUM(CASE WHEN ToBeProcessed=1 THEN 1 ELSE 0 END) ToBeProcessedIsOne
, SUM(CASE WHEN IsProcessed=1 THEN 1 ELSE 0 END) IsProcessedIsOne
FROM Records
GROUP BY JobID
HAVING SUM(CASE WHEN ToBeProcessed=1 THEN 1 ELSE 0 END)=SUM(CASE WHEN IsProcessed=1 THEN 1 ELSE 0 END)
-- Nested subquery with a condition
SELECT * FROM (
SELECT
JobID
, SUM(CASE WHEN ToBeProcessed=1 THEN 1 ELSE 0 END) ToBeProcessedIsOne
, SUM(CASE WHEN IsProcessed=1 THEN 1 ELSE 0 END) IsProcessedIsOne
FROM Records
GROUP BY JobID
) WHERE ToBeProcessedIsOne = IsProcessedIsOne
Note: if ToBeProcessed and IsProcessed are of type that does not allow values other than zero or one, you can replace the CASE statement with the name of the column, for example:
SELECT
JobID
, SUM(ToBeProcessed) ToBeProcessedIsOne
, SUM(IsProcessed) IsProcessedIsOne
FROM Records
GROUP BY JobID
HAVING SUM(ToBeProcessed)=SUM(IsProcessedD)
if im not misunderstanding your question it looks like you just need a WHERE clause in your statement to see when they are both equal to 1.
SELECT
r.JobID AS j_id,
r.RecordID as r_id,
r.ToBeProcessed AS tbp,
r.IsProcessed AS ip
FROM Records AS r
WHERE r.ToBeProcessed = 1 AND r.IsProcessed = 1
GROUP BY j_id;
let me know if this is not what you are asking for.
if its a count from a different table then just do a count of the tbp and ip rows grouped by jobID and then the where should still do the trick