My Table is as below:
EmpId section attn_status
101 Admin P
102 Admin P
103 Admin L
104 Admin A
105 Store P
106 Store L
107 Store A
108 Security P
109 Security L
110 Security P
111 Security P
I want to get results like below:
section Present Absent Late
Admin 2 1 1
Store 1 1 1
Security 3 0 1
This can be done using a group by and sum the values with a condition, like this
select t.section,
sum(case when t.attn_Status = 'P' then 1 else 0 end) as Present,
sum(case when t.attn_Status = 'L' then 1 else 0 end) as Late,
sum(case when t.attn_Status = 'A' then 1 else 0 end) as Absent
from mytable t
group by t.section
See also this DBFiddle
Related
Select p.pnum,
SUM(CASE WHEN P.NegativeScreen = 'Type99' THEN 1 ELSE 0 END) TotalDetected,
SUM(IIF(P.IsPositive = 1, 1,0)) TotalP,
SUM(CASE WHEN (P.MethId NOT IN (4, 8, 10, 25) THEN 1 ELSE 0 END) Total,
SUM(CASE WHEN (P.MethID IN (34,64) ) THEN 1 ELSE 0 END) TotalVal1,
SUM(CASE WHEN (P.MethID IN (16,64) ) THEN 1 ELSE 0 END) TotalVal2,
SUM(CASE WHEN (P.MethID IN (2,4,6,11,13,14,15,18,21,22,24,28,30,31) OR (P.MethID
= 1 AND P.TotalCount IS NOT NULL)) THEN 1 ELSE 0 END) TotalMethOther,
FROM tbl_plt p
GROUP BY P.PNum
Notice that the above query has all the fields from the tbl_plt table and SUM() is done on the fields.
Notice where I have MethID mentioned above. I need to check if those MethID exist in the tbl_plt table and if they exist in another table called TblOther. If so, tally it up accordingly.
Here is the fields in TblOther Table. Note that in TblOther table, we can have multiple PNums but the MethID will be different. Also note that for not all pNums will have entries in the TblOther table.
ID PNum MethID
1 232 32
2 232 64
3 232 10
4 104 14
5 104 54
6 22 4
7 4 13
I tried with LEFT JOIN with TblOther table but things gets messy as with the left join, it also tallies up incorrectly for places like:
SUM(CASE WHEN P.NegativeScreen = 'Type99' THEN 1 ELSE 0 END) TotalDetected,
SUM(IIF(P.IsPositive = 1, 1,0)) TotalP,
As an example for where I have:
SUM(CASE WHEN (P.MethID IN (34,64) ) THEN 1 ELSE 0 END)
it needs get the count of how many MethID exist in both the tblOther and tbl_plt for where MethID is 34 or 64 for the associated PNum.
It needs to do similarly for other places where MethID is mentioned.
I don't know enough about TblOther or it's join, but I suspect you might need to do the same group by (i.e., PNum) on it before joining on PNum. Then the left join will match either 0 or 1 records. Be sure to account for the null if there is no match.
You could start by getting the list of distinct PNum and MethIDs to use and then do your summing based on that list:
;WITH entries as (
SELECT DISTINCT PNum, MethID
FROM tblOther)
SELECT *
FROM entries
INNER JOIN tbl_plt
ON entries.PNum = tbl_plt.PNum
AND entries.MethID = tbl_plt.MethID
GROUP BY entries.PNum
Productid
Dept cd
123
440
123
422
123
248
1234
422
1234
440
1234
196
12
440
12
422
12
19
12
196
12345
196
12345
180
12345
422
** I should get the Product ID who has 422 and 440 but it should not have 248.
Answer should be 1234 and 12
There are a number of approaches to solve this one.
Here's one option that I think is simplest to understand (i.e. might not be the most efficient!):
SELECT product_id
, Sum(CASE WHEN dept_cd = 422 THEN 1 ELSE 0 END) AS has_422
, Sum(CASE WHEN dept_cd = 440 THEN 1 ELSE 0 END) AS has_440
, Sum(CASE WHEN dept_cd = 248 THEN 1 ELSE 0 END) AS has_248
FROM your_table
WHERE dept_cd IN (442, 440, 248)
GROUP
BY product_id
;
Filtering the results of that should then be trivial (make it a CTE or a subquery then add another WHERE clause, or even just use a HAVING clause).
gvee's answer using aggregation is probably the most efficient one. Simplified version (which can be easily extended):
SELECT product_id
FROM your_table
WHERE dept_cd IN (442, 440, 248)
GROUP BY product_id
HAVING -- assuming (product_id,dept_id) is unique
Sum(CASE WHEN dept_cd IN (422, 440) THEN 1 -- both exist -> result = 2
WHEN dep_cd IN (248) THEN -1 -- exists -> result < 2
END) = 2
I have a SQL query that returns to me a list of Analysts with amount of claims they've filed and the amount. I know how many Analyst there are for a specific client (6). The problem I'm having is when I run the query, only 4 pop up. If i comment out the WHERE clause (which gives me back each Analysts specific amount), I get all the Analyst, but their amounts are all the same. How do I get back the missing Analysts? I don't care if they return 0... as a matter of fact, that's what i'm trying to figure out along with the count and sums. All help is greatly appreciated. Here's my code:
SELECT
a.auditorID,
fName,
COUNT(DISTINCT case when claims.dateon >='20200726' AND claims.dateon <= '20200909' AND entries.errorCode NOT IN('DP','RB','DN','WP','WA','CE','RC','SI','CI','PE','OV') then claims.rID end) as rTotal1,
SUM(case when claims.dateon >= '20200726' AND claims.dateon <= '20200909' AND entries.errorCode NOT IN('DP','RB','DN','WP','WA','CE','RC','SI','CI','PE','OV') then entries.refundDue else 0.0 end) as rate1,
COUNT(DISTINCT case when claims.dateon >='20200726' AND claims.dateon <= '20200909' AND entries.errorCode IN('DP','RB','DN','WP','WA','CE','RC','SI','CI','PE','OV') then claims.rID end) as pTotal1,
SUM(case when claims.dateon >= '20200726' AND claims.dateon <= '20200909' AND entries.errorCode IN('DP','RB','DN','WP','WA','CE','RC','SI','CI','PE','OV') then entries.refundDue else 0.0 end) as payment1
FROM auditors a
INNER JOIN
(
SELECT auditorID, assignments.clientID FROM assignments INNER JOIN assignmentCarriers ac ON ac.acID=Assignments.acID WHERE isAssignment='True' GROUP BY auditorID, assignments.clientID
) tAssignments ON tAssignments.auditorID=a.auditorID
INNER JOIN
(
SELECT clientID, code FROM clients WHERE code='ABBL'
) tClients ON tClients.clientID=tAssignments.clientID
INNER JOIN claims ON claims.client=tClients.code
INNER JOIN entries ON claims.rID = entries.rid
WHERE claims.auditorID=a.auditorID
GROUP BY a.auditorID, fName
ORDER BY fName
Here's what I'm getting when I run the code without the SUM or COUNT...
98 User 1
99 User 2
21 User 3
61 User 4
103 User 5
172 User 6
Here's with the constraints
98 User 1 17 147346.3000 1 9451.1600
21 User 2 0 0.0000 21 182958.5100
61 User 3 5 36970.0000 81 353592.8000
103 User 4 534 319697.5774 58 234350.7900
This is the code I have
select distinct sli.order_no,
sli.pkg_no,
case when line.primary_ind = 'Y' then sum(paid_amt) else 0 end as paid_amt,
line.pkg_li_no,
sum(case when sli.perf_no = 0 then 1 else 0 end) as num_seats_pur,
sli.status
from t_sub_line sli
left outer join t_line line on sli.li_seq_no = line.li_seq_no
where sli.order_no in (1,2)
group by
sli.order_no,
sli.pkg_no,
line.primary_ind,
line.pkg_li_no,
sli.status
having line.primary_ind = 'Y'
This code produces this output
order_no pkg_no paid_amt pkg_li_no num_seats_pur status
1 322 124.00 967 2 7
1 322 -124.00 992 2 4
2 854 253.00 952 1 7
2 854 -253.00 996 1 4
what I really need for the data to return is the following. I need the sum of paid_amt field.
order_no pkg_no paid_amt pkg_li_no num_seats_pur status
1 322 0 967 2 7
2 854 0 996 1 4
even if i change status to be max(status) so its not grouping on it. I don't have sum_paid amt.
when i try this code:
sum(case when line.primary_ind = 'Y' then sum(paid_amt) else 0 end) as paid_amt,
I get the following error message
Cannot perform an aggregate function on an expression containing an aggregate or a subquery.
A couple things you need to do.
Comment out pkg_li_no from the select and group by
Change the having statement to be included in the where statement
Remove the case from paid_amt since it is not necessary
select distinct sli.order_no,
sli.pkg_no,
sum(paid_amt)as paid_amt,
-- line.pkg_li_no,
sum(case when sli.perf_no = 0 then 1 else 0 end) as num_seats_pur,
sli.status
from t_sub_line sli
left join t_line line on sli.li_seq_no = line.li_seq_no
where sli.order_no in (1,2)
and line.primary_ind = 'Y'
group by
sli.order_no,
sli.pkg_no,
line.primary_ind,
-- line.pkg_li_no,
sli.status
Other notes:
I am not sure you want to select or group by the pkg_no or status, but you know more what outcome are looking for. If they are different values, there will be different records.
I'm not sure what you're trying to accomplish, but it seems that you overthinking the query. Try to simplifying it.
FYI HAVING happens after the grouping, WHERE happens before the grouping, you don't even need the CASE
select distinct sli.order_no,
sli.pkg_no,
sum(paid_amt) as paid_amt,
sum(case when sli.perf_no = 0 then 1 else 0 end) as num_seats_pur,
sli.status
from t_sub_line sli
left outer join t_line line on sli.li_seq_no = line.li_seq_no
where sli.order_no in (1,2)
and line.primary_ind = 'Y'
group by
sli.order_no,
sli.pkg_no,
sli.status
I have three table in SQL Server 2008:
Students
StudentId Name
1 Ghanshyam
2 John
3 Pravin
Exams
ExamId ExamName
1 English
2 Math
3 SS
4 Mechanical
Marks
MarksId StudentId ExamId Marks
1 1 1 90
2 1 2 45
3 1 3 89
4 1 4 56
5 1 5 93
I want to get result display in following format:
Name English Math SS Mechnical
Ghanshyam 90 45 89 56
John 89 38 78 87
Pravin 98 40 48 38
How can I get the above result based on above three table
This is an example of Pivot tables. See
http://msdn.microsoft.com/en-us/library/ms177410.aspx
for the explanation of how to do it in MS SQL Server. Note that it is also possible to do this with standard SQL, though a bit more complicated.
Take a look at the pivot operator / Complex pivot example:
http://msdn.microsoft.com/en-us/library/ms177410.aspx
VendorID is your Name, EmpX your subjects.
Why don't you try something like this, if you do not want a pivot table?
SELECT s.Name,
SUM(CASE WHEN e.ExamName = 'English' THEN m.Marks ELSE 0 END)
/ NULLIF(COUNT(CASE WHEN e.ExamName = 'English' THEN 1 ELSE 0 END), 0) as English,
SUM(CASE WHEN e.ExamName = 'Math' THEN m.Marks ELSE 0 END)
/ NULLIF(COUNT(CASE WHEN e.ExamName = 'Math' THEN 1 ELSE 0 END), 0) as Math,
SUM(CASE WHEN e.ExamName = 'SS' THEN m.Marks ELSE 0 END)
/ NULLIF(COUNT(CASE WHEN e.ExamName = 'SS' THEN 1 ELSE 0 END), 0) as SS,
SUM(CASE WHEN e.ExamName = 'Mechanical' THEN m.Marks ELSE 0 END)
/ NULLIF(COUNT(CASE WHEN e.ExamName = 'Mechanical' THEN 1 ELSE 0 END), 0) as Mechanical
FROM students s, marks m, exams e
WHERE m.StudentID = s.StudentID
AND m.ExamID = e.ExamID