How to use multiple group by conditions in mysql - mysql

I have a customer_master table. In that table I have two columns called customer_id and date_of_birth.
what I want is get count of customers group by their age ranger. Something like this.
So far this is the only query I could try.
select COUNT(customer_id) AS count FROM customer_master
WHERE (DATEDIFF( CURDATE(),date_of_birth) / 365.25)<40
Please help me out with this. Thank you.
With everyone's help I found a perfect answer than you all.
SELECT CASE
WHEN (DATEDIFF( CURDATE(),STR_TO_DATE(date_of_birth, '%Y-%m-%d')) / 365) <= 20 THEN 'Below 20'
WHEN(DATEDIFF( CURDATE(),STR_TO_DATE(date_of_birth, '%Y-%m-%d')) / 365) <= 30 THEN 'Below 30'
WHEN (DATEDIFF( CURDATE(),STR_TO_DATE(date_of_birth, '%Y-%m-%d')) / 365) <= 40 THEN 'Below 40'
WHEN (DATEDIFF( CURDATE(),STR_TO_DATE(date_of_birth, '%Y-%m-%d')) / 365) <= 50 THEN 'Below 50'
ELSE 'Over 50'
END as age_group,
COUNT(customer_id)
FROM customer_master
GROUP BY age_group;

You can use the CASE operator.
SELECT CASE
WHEN (DATEDIFF( CURDATE(),date_of_birth) / 365.25) < 40 THEN 'Below 40'
ELSE 'Over 40'
END as age_group,
COUNT(customer_id)
FROM customer_master
GROUP BY age_group;
Sorry for poor formatting, it is my first answer

One solution would be to use cascading values with CASE within a subquery:
select age_group, count(customer_id) as 'count' from
(select customer_id,
year(curdate())-year(date_of_birth) as 'age',
case when (year(curdate())-year(date_of_birth)) < 20, "Below 20"
when (year(curdate())-year(date_of_birth)) < 30, "Between 20 and 29"
when (year(curdate())-year(date_of_birth)) < 40, "Between 30 and 39"
else "40 or Greater" end as 'age_group'
FROM customer_master) x
group by age_group

SELECT
(year(curdate())-year(date_of_birth)) div 20 as age_group,
COUNT(customer_id)
FROM
customer_master
GROUP BY age_group
Something like this will give you number of customers in every 20. If you want different size of group just change the number you divide by.
That is assuming you want each group to be same size e.g
1 - 20
21 - 40
41 - 60
...
If you want different sizes go with CASE solution as other have suggested.

Related

MySQL getting percentage of count

My Data would like this
Name Similar_Percentage
A 15
B 20
C 65
I want like this
Similar_Percentage count(*)
Less than 20 2
Less than 70 1
How to write a query for this.
I know having make this but it show one by one data.
use case when
select case when Similar_Percentage<20 then 'Less than 20'
when (Similar_Percentage<70) then 'Less than 70' end as Percentage,count(*)
from table group by case when Similar_Percentage<20 then 'Less than 20'
when (Similar_Percentage<70) then 'Less than 70' end
with cte as (
select 15 as Similar_Percentage
union all
select 20
union all
select 65
)select case when Similar_Percentage<=20 then 'Less than 20'
when (Similar_Percentage<70) then 'Less than 70' end as Percentage,count(*)
from cte group by case when Similar_Percentage<=20 then 'Less than 20'
when (Similar_Percentage<70) then 'Less than 70' end
demo link
Percentage count(*)
Less than 20 2
Less than 70 1
Another approach can be like following.
SELECT 'Less than 20' Percentage,
Count(*) [Count(*)]
FROM tablename
WHERE similar_percentage <= 20
UNION ALL
SELECT 'Less than 70' Percentage,
Count(*) [Count(*)]
FROM tablename
WHERE similar_percentage <= 70
AND similar_percentage > 20
Use a case expression in a derived table (the subquery) to do the classification. GROUP BY its result:
select percentage, count(*)
from
(
select case when Similar_Percentage <= 20 then 'Less than 20'
when Similar_Percentage <= 70 then 'Less than 70'
else 'More than 70'
end as percentage
from tablename
) dt
group by percentage
MySQL allows you to use column aliases in the group by. This simplifies the query.
I also recommend an explicit order by, so you get the results in the order you want:
select (case when Similar_Percentage <= 20 then 'Less than 20'
when Similar_Percentage < 70 then 'Less than 70'
end) as Percentage,
count(*)
from cte
group by Percentage
order by min(Similar_Percentage)

count a grouped by and cased mysql

Im trying to get the age of each person by computing on their birthday. Now I need to group them which I already achieved. Now what I want is to count how many in group 20 and below and so forth and so on.
Here's my query
select case when datediff(now(), birthday) / 365.25 > 50 then '51 & over' when datediff(now(), birthday) / 365.25 > 30 then '31 - 50' when datediff(now(), birthday) / 365.25 > 19 then '20 - 30' else 'under 20' end as age_group from members
The result is
Where I tried to group it by the query below
select case when datediff(now(), birthday) / 365.25 > 50 then '51 & over' when datediff(now(), birthday) / 365.25 > 30 then '31 - 50' when datediff(now(), birthday) / 365.25 > 19 then '20 - 30' else 'under 20' end as age_group from members group by age_group
Result will be
But what I need is somethinglike this
**NOte: Photo edited.
How do I achieved that I need to place the count result in a chart.
Wrap the query similar to this:
Select age_group, count(*)
From (
// your original query here
) t
Group by age_group
Just add a count(*) to your last query:
select case when datediff(now(), birthday) / 365.25 > 50 then '51 & over' when datediff(now(), birthday) / 365.25 > 30 then '31 - 50' when datediff(now(), birthday) / 365.25 > 19 then '20 - 30' else 'under 20' end as age_group, count(*) from members group by age_group
SELECT
concat(
datediff(now(), birthday)/365.25 div 20 * 20 + 1,
'-',
(datediff(now(), birthday)/365.25 div 20 + 1) * 20) AS age,
count(*)
FROM members
GROUP BY datediff(now(), birthday)/365.25 DIV 20
This query will give the result in the following format
+-------+----------+
| age | count(*) |
+-------+----------+
| 1-20 | 2 |
| 21-40 | 1 |
| 41-60 | 1 |
+-------+----------+
Based on the following table definition and sample data:
CREATE TABLE `stack` (
`id` int(6) NOT NULL AUTO_INCREMENT,
`birthdate` date NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
insert into members values (null,'1973-10-02');
insert into members values (null,'1977-04-07');
insert into members values (null,'2006-07-03');
insert into members values (null,'2011-10-11');

very frustrated with the mysql count function

I have racked my brain for two days on this. I need to count the members are in each age group, but cannot figure out how. I have made it this far, but this only shows the age groups of members but does not count them.
SELECT
CASE
WHEN YEAR(CURRENT_DATE()) - YEAR(birth_date) - (RIGHT(CURRENT_DATE(), 5) < RIGHT (birth_date, 5)) BETWEEN 12 AND 18 THEN '12-18'
WHEN YEAR(CURRENT_DATE()) - YEAR(birth_date) - (RIGHT(CURRENT_DATE(), 5) < RIGHT (birth_date, 5)) BETWEEN 19 AND 55 then '19-55'
ELSE '56 or older'
END AS age_group
FROM members
ORDER BY age_group
You have already extracted the data you need. To count it, embed it as a sub query and count the results for each group via a group by clause. By adding the unique identifier for each member in the sub query, it allows the counts of the members in each group to survive the group by (ie. Not get collapsed into a single row per group).
SELECT age_group, COUNT(*) AS group_count
FROM
(SELECT
- - add a unique identifier for each member here as a select attribute,
CASE
WHEN YEAR(CURRENT_DATE()) - YEAR(birth_date) - (RIGHT(CURRENT_DATE(), 5) < RIGHT (birth_date, 5)) BETWEEN 12 AND 18 THEN '12-18'
WHEN YEAR(CURRENT_DATE()) - YEAR(birth_date) - (RIGHT(CURRENT_DATE(), 5) < RIGHT (birth_date, 5)) BETWEEN 19 AND 55 then '19-55' ELSE '56 or older' END AS age_group
FROM members) AS tab_age_groups
GROUP BY age_group
ORDER BY age_group;
You need to tell the query to perform a count. You also need to group by the field you want counted.
Try this:
select count(*) as the_count,
case
when YEAR(CURRENT_DATE()) - YEAR(birth_date) - (RIGHT(CURRENT_DATE(), 5) < RIGHT (birth_date, 5)) between 12 AND 18 THEN '12-18'
when YEAR(CURRENT_DATE()) - YEAR(birth_date) - (RIGHT(CURRENT_DATE(), 5) < RIGHT (birth_date, 5)) between 19 AND 55 then '19-55'
else '56 or older'
end
as age_group
from members group by age_group order by age_group;
Click the link below for a running demo:
SQLFiddle

Using case when mysql

I would like to query a total marks column using case and get the marks respective grades and store it as a separate column. I have been trying for a while now, but it keeps giving me errors.
SELECT gradecalc.StudentId,gradecalc.CourseCode, Total,
CASE TOTAL
WHEN >90 THEN 'AA'
WHEN <90 AND >85 THEN 'BA'
WHEN <85 AND >=80 THEN 'BB'
WHEN <80 AND >=75 THEN 'CB'
WHEN <75 AND >=70 THEN 'CC'
WHEN <70 AND >=65 THEN 'DC'
WHEN <65 AND >=60 THEN 'DD'
ELSE 'FF'
END AS Grade
FROM GRADECALC GROUP BY gradecalc.StudentId,gradecalc.CourseCode
The case <column> when <value> syntax can only handle equality checks. For other operators, your'd have to use a slightly different syntax:
SELECT gradecalc.StudentId,gradecalc.CourseCode, Total,
CASE
WHEN total > 90 THEN 'AA'
WHEN total < 90 AND total >= 85 THEN 'BA'
WHEN total < 85 AND total >= 80 THEN 'BB'
WHEN total < 80 AND total >=75 THEN 'CB'
WHEN total < 75 AND total >=70 THEN 'CC'
WHEN total < 70 AND total >=65 THEN 'DC'
WHEN total < 65 AND total >=60 THEN 'DD'
ELSE 'FF'
END AS Grade
FROM GRADECALC GROUP BY gradecalc.StudentId,gradecalc.CourseCode
You need to put the full expression in the case when. Your syntax of case <variable> when <constant> only works for constants.
Now, you can also simplify the expressions, because case is processed in order. So this is equivalent logic:
SELECT gc.StudentId, gc.CourseCode, gc.Total,
(CASE WHEN TOTAL > 90 THEN 'AA'
WHEN TOTAL > 85 THEN 'BA'
WHEN TOTAL >= 80 THEN 'BB'
WHEN TOTAL >= 75 THEN 'CB'
WHEN TOTAL >= 70 THEN 'CC'
WHEN TOTAL >= 65 THEN 'DC'
WHEN TOTAL >= 60 THEN 'DD'
ELSE 'FF'
END) AS Grade
FROM GRADECALC gc
GROUP BY gc.StudentId, gc.CourseCode ;
I don't think the GROUP BY is necessary, unless you have multiple rows for a given student and course. If you do, then you probably want AVG(Total) or something like that in the case statement.
With this formulation, you can readily see that "90" and "85" are suspicious. In fact, your original logic would give students with these marks an "FF", which I'm guessing is not the intention.
So:
SELECT gc.StudentId, gc.CourseCode, gc.Total,
(CASE WHEN TOTAL >= 90 THEN 'AA'
WHEN TOTAL >= 85 THEN 'BA'
WHEN TOTAL >= 80 THEN 'BB'
WHEN TOTAL >= 75 THEN 'CB'
WHEN TOTAL >= 70 THEN 'CC'
WHEN TOTAL >= 65 THEN 'DC'
WHEN TOTAL >= 60 THEN 'DD'
ELSE 'FF'
END) AS Grade
FROM GRADECALC gc;
You can try this, mate:
SELECT
gc.StudentId,
gc.CourseCode,
gc.Total,
CASE
WHEN gc.Total > 90 THEN 'AA'
WHEN gc.Total BETWEEN 85 AND 90 THEN 'BA'
WHEN gc.Total BETWEEN 80 AND 85 THEN 'BB'
WHEN gc.Total BETWEEN 75 AND 80 THEN 'CB'
WHEN gc.Total BETWEEN 70 AND 75 THEN 'CC'
WHEN gc.Total BETWEEN 65 AND 70 THEN 'DC'
WHEN gc.Total BETWEEN 60 AND 65 THEN 'DD'
ELSE 'FF'
END AS Grade
FROM
gradecalc gc
GROUP BY
gc.StudentId, gc.CourseCode;

How to calculate age from date of birth and group each member into age range in sql

I have an sql table that stores people's details i.e id, name, DoB, registration_date and address. I would like to calculate the age of each individual and then group them into these ranges: 20-30, 31-50, 51 & over.
I know i can get the age by doing: (https://stackoverflow.com/a/1572257/3045800)
SELECT FLOOR((CAST (GetDate() AS INTEGER) - CAST(Date_of_birth AS INTEGER)) / 365.25) AS Age
I just need to figure out how to group all people into thier respective range.
Thanks for the help
Use a case to produce the age group description:
select *,
case
when datediff(now(), date_of_birth) / 365.25 > 50 then '51 & over'
when datediff(now(), date_of_birth) / 365.25 > 30 then '31 - 50'
when datediff(now(), date_of_birth) / 365.25 > 19 then '20 - 30'
else 'under 20'
end as age_group
from person
Note the simpler way to calculate age.
You can use with construction:
with Query as (
select FLOOR((CAST (GetDate() AS INTEGER) - CAST(Date_of_birth AS INTEGER)) / 365.25) AS Age
... -- Other fields
from MyTable
)
select case
-- whatever ranges you want
when (Age < 20) then
1
when (Age >= 20) and (Age <= 30) then
2
when (Age > 30) and (Age <= 50) then
3
else
4
end AgeRange,
...
from Query
group by AgeRange
I was once faced with the same requirement and this is How I fixed it: I wish there was a Straight Forward way as this is Not:
SELECT (CASE
WHEN G.DATE_OF_BIRTH IS NULL
THEN
'18-24' --Put your default Range In case the date of birth is null
ELSE
CASE
WHEN EXTRACT (
YEAR FROM (select sysdate from dual))
- EXTRACT (YEAR FROM g.DATE_OF_BIRTH) < 18
THEN
'MINORS'
ELSE
CASE
WHEN EXTRACT (
YEAR FROM (select sysdate from dual))
- EXTRACT (YEAR FROM g.DATE_OF_BIRTH) BETWEEN 25
AND 29
THEN
'25-29'
ELSE
CASE
WHEN EXTRACT (
YEAR FROM (select sysdate from dual))
- EXTRACT (YEAR FROM g.DATE_OF_BIRTH) BETWEEN 30
AND 34
THEN
'30-34'
ELSE
CASE
WHEN EXTRACT (
YEAR FROM (select sysdate from dual))
- EXTRACT (
YEAR FROM g.DATE_OF_BIRTH) BETWEEN 35
AND 39
THEN
'35-39'
ELSE
CASE
WHEN EXTRACT (
YEAR FROM (select sysdate from dual))
- EXTRACT (
YEAR FROM g.DATE_OF_BIRTH) BETWEEN 40
AND 49
THEN
'40-49'
ELSE
CASE
WHEN EXTRACT (
YEAR FROM (select sysdate from dual))
- EXTRACT (
YEAR FROM g.DATE_OF_BIRTH) BETWEEN 50
AND 59
THEN
'50-59'
ELSE
CASE
WHEN EXTRACT (
YEAR FROM (select sysdate from dual))
- EXTRACT (
YEAR FROM g.DATE_OF_BIRTH) BETWEEN 60
AND 69
THEN
'60-69'
ELSE
CASE
WHEN EXTRACT (
YEAR FROM (select sysdate from dual))
- EXTRACT (
YEAR FROM g.DATE_OF_BIRTH) >=
70
THEN
'ELDERLY'
END
END
END
END
END
END
END
END
END) from your table g
This is just example. Replace the ranges with your Preferred Ones. This I have done using Oracle.