How to count number of items in MySQL? - mysql

It is better explained in example.
I have the following data in MySQL
Name address age
John1 33 St 20
John2 22 St 21
John3 44 St 20
John4 55 St 21
John6 44 St 20
John5 66 St 35
I would like to get list of rows with counts based on age. But is it possible to get the last row associate with each count. Example
Name address age Count
John6 44 St 20 3
John4 55 St 21 2
John5 66 St 35 1

Check out the syntax for GROUP BY
SELECT *, count(*) as Count FROM tableName GROUP BY age;
UPDATE
Let's assume you decide to add an ordering column, like a datetime:
Name address age created
John1 33 St 20 2011-04-01 10:00:00
John2 22 St 21 2011-04-01 09:00:03
John3 44 St 20 2011-04-01 07:00:20
John4 55 St 21 2011-04-01 08:45:01
John6 44 St 20 2011-04-01 13:00:00
John5 66 St 35 2011-04-01 12:00:40
Then you could accomplish your final goal like so:
SELECT *, count(*) as Count
FROM ( SELECT * FROM tableName ORDER BY created DESC ) as newTable
GROUP BY age;
You must use a nested select because otherwise ORDER BY would be applied after GROUP BY.

As Stephen pointed out, you need to do a nested select, but the other way around:
SELECT
u.Name,u.Address, u.age, u.NumCount
FROM (SELECT Name, Address, age, count(age) from users group by age) as u
ORDER BY u.NumCount desc

Related

Get max score and store in another column

This is my table:
student_id
subject_id
total
max
101
1
90
102
2
80
103
1
95
101
1
82
103
2
76
104
1
95
101
2
71
I want to get the max total in a particular subject and store it in another column whenever the total column is inserted or updated.
This is what I want the table to look like:
student_id
subject_id
total
max
101
1
90
95
102
2
80
80
103
1
95
95
101
1
82
95
103
2
76
80
104
1
95
95
101
2
71
80
I have tried this query but it doesn't add the max scores in each subject against all the student_id.
SELECT MAX(`total`) AS highest
FROM results
GROUP BY student_id
I suppose I should use a trigger for this but the normal query is also okay by me.
If your column does not yet exist in your table, you need to add it with an ALTER statement.
ALTER TABLE <your_table_name> ADD max INT;
Then you can first select the "max" value for each "subject_id" using an aggregation, then use it inside the UPDATE statement exploiting a JOIN operation:
UPDATE <your_table_name>
INNER JOIN (SELECT subject_id,
MAX(total) AS total_max
FROM <your_table_name>
GROUP BY subject_id) cte
ON <your_table_name>.subject_id = cte.subject_id
SET <your_table_name>.max = cte.total_max;
Check the demo here.
Assuming you are using MySQL 8+.
Ideally, instead of storing MaxTotal data into each column, you should get such the data while selecting like this:
WITH CTE AS (SELECT subject_id,MAX(total) AS MaxTotal
FROM results
GROUP BY subject_id
)
SELECT results.*,CTE.MaxTotal
FROM results
JOIN CTE ON results.subject_id = CTE.subject_id;
However, if you still need to update it anyway, use UPDATE with JOIN
WITH CTE AS (SELECT subject_id,MAX(total) AS MaxTotal
FROM results
GROUP BY subject_id
)
UPDATE results
JOIN CTE ON results.subject_id = CTE.subject_id
SET results.MaxTotal = CTE.MaxTotal;
Output after the update:
student_id
subject_id
total
MaxTotal
101
1
90
95
102
2
80
80
103
1
95
95
101
1
82
95
103
2
76
80
104
1
95
95
101
2
71
80
See this db<>fiddle.

Calculate the number of users based on the below conditions by writing a single query SQL

There are two campaigns running campaign A and Campaign B and list of user ids participated in those two campaign is given below. Calculate the number of users based on the below conditions by writing a single query.
Participated in campaign A
Participated in campaign B
Participated in campaign A only
Participated in campaign B only
Participated in both the campaigns
Participated in either campaign A or Campaign B
Campaign A Campaign B
user_id user_id
91 62
27 11
58 16
50 92
64 17
65 71
54 12
98 37
78 93
24 58
31 54
73 94
63 85
72 30
94 32
20 1
38 48
8 99
43 45
33 46
26 39
100 29
61 49
87 73
84 81
15 88
80 70
77 33
40 55
82
42
56
95
88
I am not able to figure out how to write in single SQL query.
Assuming you have two different tables, you can use union all and aggregation:
select in_a, in_b, count(*) as num_users
from ((select user_id, 1 as in_a, 0 as in_b
from a
) union all
(select user_id, 0 as in_a, 1 as in_b
from b
)
) u
group by in_a, in_b;
This gives you all the information you need. You can use group by in_a, in_b with rollup to get all combinations.
Or, you can summarize this into one row:
select sum(in_a) as in_a, sum(in_b) as in_b,
sum(in_a * (1 - in_b)) as in_a_only,
sum(in_b * (1 - in_a)) as in_b_only,
sum(in_a * in_b) as in_ab
from ((select user_id, 1 as in_a, 0 as in_b
from a
) union all
(select user_id, 0 as in_a, 1 as in_b
from b
)
) u;
Note: These both assume that users are unique in each campaign. If not, just use select distinct or union in the subquery.

SQL COUNT giving same value

I have a table that looks like this...
Attendance_ID person_ID Meeting_ID date
--------------- --------- ---------- ----------
23 25 123 2013-03-21
24 25 456 2013-03-21
25 25 789 2013-03-21
26 13 147 2013-03-21
27 25 123 2013-03-22
28 82 147 2013-03-22
29 82 456 2013-03-22
30 13 147 2013-03-23
31 25 456 2013-03-23
32 13 456 2013-03-24
33 25 456 2013-03-28
The goal is to print out all the the times a employee has missed one or more meetings during the day. I have tried the following query but it gives me the same result of 2 for all dates...
SELECT
replace(replace(dayname(date),"Saturday", "Weekend"),"Sunday", "Weekend") AS day,
count(distinct personID) AS absences
from
AttendanceRecord
GROUP BY
day;
where it should be...
Friday 2
Thursday 3
Weekend 3
Where am I going wrong? Any help would be welcome as my SQL skills are a bit rusty. Thanks!
This is MySQL, and the table above is the dates of absences. So if the emplyee missed meeting 123, they would show up on this table. The query is to see the number of employees who missed a meeting on that day.
count(distinct personID) AS absences
should be
count(distinct employeeID) AS absences
because if you see your example data you have:
Employee ID person ID Meeting ID date
----------- --------- ---------- ----------
23 25 123 2013-03-21
24 25 456 2013-03-21
25 25 789 2013-03-21
where these 3 different Employees have the same Person ID
Either that, or you're already getting the correct values; there are 10 different EmployeeID but there are fewer than that PersonID
If you still want to count repeated personIDs, then change
count(distinct personID) AS absences
to
count(personID) AS absences
Could be, as long as every meeting was attended by at least one person.
WITH ALL_MEETING_EMPLOYEE_COMBOS AS
( SELECT EmployeeID,
Meeting_ID,
date
FROM (SELECT DISTINCT
Employee_ID
FROM Attendance_Record
)
CROSS JOIN
( SELECT DISTINCT
meeting_id,
date
FROM attendance_record
)
)
SELECT Employee_ID,
Date,
COUNT(1) AS MissedOnThisDayCount
FROM ALL_MEETING_EMPLOYEE_COMBOS T1
WHERE NOT EXISTS
( SELECT 1
FROM ATTENDANCE_RECORD AR
WHERE T1.employee_id = AR.employee_id
AND T1.meeting_id = AR.meeting_id
)
GROUP BY employee_id, date

MySQL sum of counts of two queries

I am (very) new to MySQL. Forgive my lack of knowledge....
I am working on a hockey stat database where I need to add all the assists and all the goals together to get "total points". I have two queries already figured out, but I am not able to figure out how to sum the two.
Here are the queries:
select player_id, count(*)
from(select * from 1st_assists
union
select * from 2nd_assists) as tem
join players on tem.fk_player_id=players.player_id
group by fk_player_id
order by count(*) desc
select player_id, count(*)
from goals_for
join shots_for on goals_for.fk_shot_for_id=shots_for.shot_for_id
join players on shots_for.fk_player_id=players.player_id
group by player_id
order by count(*) desc;
how do I combine these two queries into one and get the total of both counts?
Here are the results of each of the queries
Total Assists
player_id count(*)
79 24
55 22
45 17
90 16
40 15
65 15
37 13
1 13
20 11
84 11
64 10
27 9
93 7
8 5
24 3
57 1
Goals
player_id count(*)
90 38
37 28
40 19
55 13
45 11
1 8
24 8
20 8
84 8
27 6
8 5
79 4
65 4
93 1
64 1
It is untested, but can you, please, try this:
select p.player_first_name, p.player_last_name, (count1+count2) as total_count
from
(select player_id, count(*) count1
from(select * from 1st_assists
union
select * from 2nd_assists) as tem
join players on tem.fk_player_id=players.player_id
group by fk_player_id
order by count(*) desc) q1
left join
(select player_id, count(*) count2
from goals_for
join shots_for on goals_for.fk_shot_for_id=shots_for.shot_for_id
join players on shots_for.fk_player_id=players.player_id
group by player_id) q2
ON q1.player_id=q2.player_id
left join player p ON q1.player_id=p.player_id
order by (count1+count2) desc;

SQL Count Average

I have table like
id userid semid courseid coursename total
1 36 17 13 CA 23
2 36 17 5 CB 46
3 36 17 8 CC 20
4 36 19 16 CD 34
5 36 19 13 CA 31
6 36 19 3 CA# 29
7 36 19 7 CE 60
8 36 10 9 CK 32
9 36 10 15 CH 56
I need average of semid for a userid i.e., SUM(courseid) /count (moduleid), It was showing 9 as module count, but I have only 3 modules.
This is my query
SELECT userid, SUM(total)/count(semid) FROM custom WHERE userid=36
just use the AVG( ) function
SELECT userid, semid, AVG(total)
FROM custom
WHERE userid = 36
GROUP BY userid, semid
SQLFiddle Demo
SELECT userid, SUM(total)/count(distinct semid) FROM custom WHERE userid=36
Try this query
There is MYSQL aggregate function AVG() for finding Average . #John Totet Woo has posted the answer.