Using a case statement to show the count of two types of values in a column - sql

SELECT
qt.name,
CASE
WHEN qr.isfinished = 0 THEN COUNT(qr.resultid)
END AS 'Attempted',
CASE
WHEN qr.isfinished = 1 THEN COUNT(qr.resultid)
END AS 'Completed'
Need it to show attempted and completed values on the same row
Name attempted Completed
--------------------------------
Algebra I 114 NULL
Algebra II 47 NULL
ASVAB 55 NULL
Algebra I NULL 69
Algebra II NULL 55
ASVAB NULL 84
Thank you for the help!

If isfinished is bit, you can't aggregate on it.
And the CASE goes inside the COUNT
SELECT qt.name,
count(Case when qr.isfinished = 0 THEN 1 END) as 'Attempted',
count(Case when qr.isfinished = 1 THEN 1 END) as 'Completed'
FROM
...
GROUP BY
qt.name

There are multiple ways you could do this, for example you could do this with joins, or you can use group by -- like so:
SELECT
qt.name,
SUM(CASE qr.isfinsihed WHEN 1 THEN 1 ELSE 0) AS 'Attempted',
SUM(CASE qr.isfinished WHEN 0 THEN 1 ELSE 0) AS 'Completed'
FROM -- what ever your from clause is, it goes here --
GROUP BY
qt.name
In order to have them on the same row, you will need to group by what they have in common. From what you have given in the question, I am assuming that is the qt.name.
Next, you can use the SUM aggregate to get each field count. All of the records that meet the criteria for each item count towards the sum, the others don't. You can also use count with 1's and Null's, I prefer using Sum because it can allow for weighted totals if I need them.

Related

Oracle SQL: Using COUNT() >1 When Combining two CASE WHEN Statements

I have a line of SQL which produces a count of purchases variable
count(distinct case when t.transaction_sub_type =1 then t.transaction_date end) as COUNTPUR,
I need to modify this so I can produce a 0/1 flag variable, which flags if a customer is a repeat purchaser. So, when a customer's purchases are greater than 1 then flag as 1 else flag as 0.
case when COUNTPUR>1 then 1 else 0 end as FLAG_REPEATPURCHASER
I need to combine these two case statements into one. I have been experimenting with different versions of the syntax, but I can't seem to nail it down. Below is one of the experiments which do not work.
max(case when (count(distinct case when t.transaction_sub_type =1 then t.transaction_date end))>1 then 1 else 0 end) as FLAG_REPEATPURCHASER,
Thanks in advance for assitance
You can use a case expression with conditional aggregation:
(case when count(distinct case when t.transaction_sub_type = 1 then t.transaction_date end) > 1
then 1 else 0
end) as FLAG_REPEATPURCHASER

Aggregate sub-query not producing expected results

I have two tables and there's a one to many relationship between the two. My query has a group by and I want to determine if there are any results in the 2nd table that match some criteria. I couldn't figure it out with a sub-query and tried the following code, but it's not giving you the results you expect.
CASE WHEN
(SELECT SUM(CASE WHEN a.ContentId IS NULL THEN 1 ELSE 0 END)) > 0
THEN 1
ELSE 0
END as 'HasAttachments'
Basically, I am trying to figure out if my message (which could have many attachments) has any attachments where the ContentId is null and if that count is greater than 0 then I want to return the boolean value in HasAttachments.
Any help would be great!
CASE WHEN
SUM(CASE WHEN a.ContentId IS NULL
AND a.message_id IS NOT NULL
THEN 1
ELSE 0
END) > 0
THEN 1
ELSE 0
END as HasAttachments
From your narratives it seems like your inner Case Statement is missing another condition to determine when there is actually an attachment. If you don't put in the second condition of when the AttachmentTable.message_id IS NOT NULL then you will count both messages that don't have any attachments and those messages that have attachments but no content id as the same thing. But adding the a.message_id you limit that to just the case you seem to desire from your narrative.
Here is one way I might phrase the query:
select m.*,
(case when exists (select 1 from attachments a where a.message_id = m.message_id and content_id is null
)
then 1 else 0
end) as HasAttachments
from messages m;
It is unclear why your query doesn't work, without the context of the rest of the query.

Use of sum and count inside a case statement in sql

select req.code ,res.code,
case
(
when (req.code==res.code) then 'pass'
when (req.code<>res.code) then 'fail'
/*....2 more case 'when' 'then' statements here*/
end ) result,
req.country ,res.country,
case (when then staments as above)result,
/*.......case stmts upto 70 statemnts*/
from requesttable req full outer join responsetable res on
req.id=res.id
and ....some conditions.
Can anyone tell me how can I sum every column and display the sum as well as the count of records in every column of both tables simultaneously and display count in my query?
My result should be of this sort
code code1 result sum sum1 equivalence country country1 result1 sum sum1
100 100 pass 200000 25000 fail ind aus fail 800000 800000
equivalence
pass
I am trying to prepare a report joining two tables. I am using multiple case statements to accomplish this. I want to display sum of each column and count of each column of both the tables together in a single report. The query that I have is of the following type.
I think this is kind of what you're looking for. For the code and country values displayed on the line it would give you the pass and fail accounts for the combinations displayed and you would have uniqueness on the columns the aggregate is defined on.
Select req.code,
res.code,
Sum(Case When req.code = res.code) Then 1 Else 0 End) As [Pass],
Sum(Case When req.code <> res.code) Then 1 Else 0 End) As [Fail],
req.country,
res.country,
Sum(Case When req.country = res.country) Then 1 Else 0 End) As [Pass],
Sum(Case When req.country <> res.country) Then 1 Else 0 End) As [Fail]
From requesttable req
Full Outer Join responsetable res
On req.id = res.id
Where ...
Group By req.code,
res.code,
req.country,
res.country

aggregations in case statement

I am trying to do aggregations in case statement. I found 2 ways to do it. Can anyone say what the difference between the 2 is?
(CASE WHEN Event = 5 THEN count(*) ELSE 0 END ) Follow_Count
GROUP BY Event;
SUM(CASE Event WHEN 5 THEN 1 ELSE 0 END) AS Follow_Count
Your case 1 will produce a row for each event in the table (from your group by). Your case 2 will just return 1 row.
Is there a reason that you wouldn't just write:
select count(*)
from my_table
where event = 5;
Better would be:
count(CASE Event WHEN 5 THEN 1 END) AS Follow_Count
Because
1) for count used own standart counter,
2) "else" not need (count don't count nulls)
Regards,
Sayan M.
There is no significant difference. You can decide for you which is better by comparing their execution plans.

How to COUNT column values differently in a VIEW?

I have a column in Datablase Table, Suppose its Observation which contains three types of values
Positive
Negative
NULL
Now I want to count the Total no of rows , Total Positive and Total Negative and some other columns. I can not use Where clause here. And its a view
So result should be like
Total Positive Negative SomeOtherCoulumn
255 80 120 Test1
315 135 65 Test2
I tried to use SQL COUNT here but could not get the desired results.
SELECT
COUNT(*) AS Total,
SUM(CASE WHEN Observation = 'Positive' THEN 1 ELSE 0 END) AS Positive,
SUM(CASE WHEN Observation = 'Negative' THEN 1 ELSE 0 END) AS Negative,
SomeOtherColumn
FROM your_view
GROUP BY SomeOtherColumn
There's an interesting technique of summing a case expression like so:
sum(case when Observation = 'Positive' then 1 else 0 end) 'TotalPositive'
The rest is easy.