using sql count in a case statement
SELECT
COUNT(CASE WHEN rsp_ind = 0 then 1 ELSE NULL END) as "New",
COUNT(CASE WHEN rsp_ind = 1 then 1 ELSE NULL END) as "Accepted"
from tb_a
You can see the output for this request HERE
Conditional COUNT within CASE statement
You were nearly there! I've made a few changes:
SELECT
DATEFROMPARTS(YEAR(t1.Date), MONTH(t1.Date),1) AS Draft_Date,
Membership,
COUNT(CASE WHEN t1.Membership = 5 AND t1.Service_Type = 'A' THEN 1 END) as m5stA,
COUNT(CASE WHEN t1.Membership = 2 AND t1.Service_Type IN ('J','C') THEN 1 END) as m2stJC
FROM Table1 t1
GROUP BY YEAR(t1.Date), MONTH(t1.Date), Membership
Changes:
- Avoid using apostrophes to alias column names, use ascii standard " double quotes if you must
- When doing a conditional count, put the count outside the CASE WHEN, and have the case when return something (any non null thing will be fine - i used 1, but it could also have been 'x' etc) when the condition is met. Don't put an ELSE - CASE WHEN will return null if there is no ELSE and the condition is not met, and nulls don't COUNT (you could also write ELSE NULL, though it's redundant)
- Qualify all your column names, always - this helps keep the query working when more tables are added in future, or even if new columns with the same names are added to existing tables
- You forgot a THEN in the second WHEN
- You don't necessarily need to GROUP BY the output of DATEFROMPARTS. When a deterministic function is used (always produces the same output from the same inputs) the db is smart enough to know that grouping on the inputs is also fine
- Your example data didn't contain any data that would make the COUNT count 1+ by the way, but I'm sure you will have other conditional counts that work out (it just made it harder to test)
How to use count for a case statement
I feel that you should be doing the outer count rollups over a subquery which aggregates by order:
SELECT
COUNT(CASE WHEN sales < 5000 THEN 1 END) AS Low,
COUNT(CASE WHEN sales < 9999 THEN 1 END) AS Medium,
COUNT(CASE WHEN sales >= 9999 THEN 1 END) AS High
FROM
(
SELECT o.[Order ID], SUM(o.Sales) AS sales
FROM Orders o
INNER JOIN Returns r ON o.[Order ID] = r.[Order ID]
GROUP BY o.[Order ID]
) t;
That being said, I don't actually know what the purpose of joining Orders
to the Returns
table is. If you intend to only find sales amounts from orders which have been returned, then maybe this makes sense. Otherwise, maybe it doesn't make sense.
How best to Count(*) with a CASE STATEMENT?
I tend to like sum()
SELECT
SUM(CASE WHEN <conditions> THEN 1 ELSE 0 END) as conditionalcountall
FROM TABLE
SQL Case statement with Count?
Use aggregation:
select p.person_nbr,
(case when min(ml1.mstr_list_item_desc) = max(ml1.mstr_list_item_desc)
then min(ml1.mstr_list_item_desc)
else 'Unknown'
end) as final_ethnicity
from person_table p left join
person_ethnicity_xref eth1
on p.person_id = eth1.person_id left join
mstr_lists ml1
on eth1.ethnicity_item_id = ml1.mstr_list_item_id
group by p.person_nbr;
Note: This slightly tweaks your logic. If there a multiple ethnicities and they are all the same, then that value is used.
MySQl using COUNT with CASE statement
You should count 1 for a match, and count NULL
when there is no match:
SELECT
account_id,
COUNT(CASE WHEN action_type = 1 AND action_name = 'like' THEN 1 END) AS `like`,
COUNT(CASE WHEN action_type = 1 AND action_name = 'superLike' THEN 1 END) AS superLike,
COUNT(CASE WHEN action_type = 2 THEN 1 END) AS follow
FROM instagram_actions_histories
WHERE account_id IN (1)
GROUP BY account_id;
The problem with the current logic of your CASE
expressions is that COUNT
will count any non null value as one count. So zero also would be counted.
Note that your current logic would have worked using SUM
to take the conditional aggregations, e.g.
SUM(CASE WHEN action_type = 1 AND action_name = 'like'
THEN 1 ELSE 0 END) AS `like`
In this case, to turn off the aggregation for non matching records, we in fact can use zero, because summing zero does not affect the sum.
count and sum in case statement
The three are equivalent. All of them count the number of rows that meet the particular condition (salary > 100000
). All return 0
/1
and would not return NULL
values for the column.
From a performance perspective, all should be equivalent as well. I have a personal preference for the first version. I consider the third to be unnecessarily verbose because else NULL
is the default for a case
expression.
Count Nested Case in SQL
COUNT( CASE trans.id_user WHEN 1 THEN 1
CASE trans.id_train WHEN 1 THEN 1
ELSE NULL END ) AS total_ticket
Unclear construction. Looks like you need one of below variants.
COUNT( CASE WHEN trans.id_user = 1 THEN 1
WHEN trans.id_train = 1 THEN 1
ELSE NULL END ) AS total_ticket
-- which may be simplified to
SUM(1 IN (trans.id_user, trans.id_train)) AS total_ticket
COUNT( CASE WHEN trans.id_user = 1
AND trans.id_train = 1 THEN 1
ELSE NULL END ) AS total_ticket
-- which may be simplified to
SUM(trans.id_user = 1 AND trans.id_train = 1) AS total_ticket
Related Topics
How to Change a Table Name Using an SQL Query
How to Drop Multiple Tables in Postgresql Using a Wildcard
SQL Select Multi-Columns into Multi-Variable
Oracle: How to Get Percent of Total by a Query
Why Can't I Use "Create Schema" in a Begin/End Block in SQL Management Studio
Referencing Outer Query's Tables in a Subquery
Designing 1:1 and 1:M Relationships in SQL Server
Ms SQL Server - How to Create a View from a Cte
Adding an One-Out-Of-Two Not Null Constraint in Postgresql
SQL Server Script to Create a New User
Oracle - What Statements Need to Be Committed
Why Does SQL Server Keep Executing After Raiserror When Xact_Abort Is On
SQL Get All Records Older Than 30 Days
Do Indexes Work with "In" Clause
SQL Bulk Insert with Firstrow Parameter Skips the Following Line