How to use Group By and Having together - mysql

I have following data set
id name units release_date
1 salil 1 2012-04-02
2 salil 2 2012-03-21
3 salil 3 2012-04-02
4 salil 4 2012-03-02
5 salil 5 2012-04-02
6 xyz 1 2012-04-01
7 xyz 2 2012-03-30
8 xyz 3 2012-03-30
9 xyz 4 2012-04-01
I want the SUM of an unit for Maximum date for each name. something like follwing
name units Max(release_date)
salil 9 2012-04-02
xyz 5 2012-04-01
I try following but it is not working
SELECT name, MAX(release_date) as date, sum(units) as units FROM reports
GROUP BY name;

Try below :
SELECT name, sum(units) as units
FROM reports as r
LEFT JOIN (select max(date) as maxdate from reports group by name ) as mr
ON r.date=mr.maxdate
WHERE artist_name='Pacer1' GROUP BY name;

Related

how to generate student attendance percentage per course, when they have specific day in a week

hi guys i really newbie in sql, i need help to generate percentage of attendance, here is the table:
Table Schedule
Schedule_ID Course_ID Lecture_ID Start_Date End_Date Course_Days
1 1 11 2019-09-09 2019-12-08 2,4,6
2 3 4 2019-09-09 2019-12-08 3,4
3 4 13 2019-09-09 2019-12-08 2,5
4 5 28 2019-09-09 2019-12-08 3
5 2 56 2020-01-27 2020-04-26 2,4
6 7 1 2020-01-27 2020-04-26 4,5
7 1 11 2020-01-27 2020-04-26 2,4,6
8 7 22 2020-01-27 2020-04-26 2,3
9 8 56 2020-01-27 2020-04-26 5
10 3 37 2020-01-27 2020-04-26 5,6
Reference of days of week used in this data.
1: Sunday, 2:Monday, 3:Tuesday, 4:Wednesday, 5:Thursday, 6:Friday, 7:Saturday
Table course_attendance
ID STUDENT_ID SCHEDULE_ID ATTEND_DT
1 1 2 2019-09-10
2 1 2 2019-09-11
3 1 2 2019-09-17
4 1 2 2019-09-18
......
46 2 1 2019-12-02
47 2 1 2019-09-11
48 2 1 2019-09-18
49 2 1 2019-09-25
50 2 1 2019-10-09
51 2 1 2019-10-16
....
111 6 1 2019-09-23
112 6 1 2019-09-30
113 6 1 2019-10-07
114 6 1 2019-10-14
table student
ID NAME
1 Jonny
2 Cecilia
3 Frank
4 Jones
5 Don
6 Harry
i need to show up like this :
STUDENT_ID NAME Course_ID Attendance rate
1 Jonny 1 82%
2 Cecilia 1 30%
3 Frank 3 100%
4 Jones 2 100%
5 Don 2 25%
6 Harry 4 40%
EDIT this my last step to get percentage:
result:
with main as (
select ca.STUDENT_ID,
ca.SCHEDULE_ID,
s.COURSE_ID,
co.NAME as course_name,
st.NAME,
count(ca.ID) as total_attendance,
((CHAR_LENGTH(s.COURSE_DAYS) - CHAR_LENGTH(REPLACE(s.COURSE_DAYS , ',', '')) + 1) * 13) as attendance_needed
from univ.course_attendance ca
left join univ.schedule s on ca.SCHEDULE_ID = s.ID
left join univ.student st on ca.SCHEDULE_ID = st.ID
left join univ.course co on ca.SCHEDULE_ID = co.ID
group by ca.STUDENT_ID, ca.SCHEDULE_ID
)
select *,total_attendance/attendance_needed as attendance_percentage
from main
order by 1,2;
This can be done following three steps.
Step 1: Calculate the total number of days a particular course of a schedule has. It's a good thing the start_date is always on Monday and the end_date is always on Sunday, which makes the week complete and saves some trouble. By calculating the total number of weeks a course go through and the number of days a week has for that course, we can get the total number of days a particular course of a schedule has.
Step 2:Calculate the total number of days a student for a schedule. This is done fairly easily. Note: As the majority part of the table has been skipped and the OP has yet to provide the complete data set, I could only have 14 existing rows provided.
Step 3: Calculate the percentage for the attendance using the result from the above two steps and get other required columns.
Here is the complete statement I wrote and tested in workbench:
select t2.student_id as student_id,`name`,course_id, (t2.total_attendance/t1.total_course_days)*100 as attendance_rate
from (select schedule_id,course_id,
length(replace(course_days,',',''))*(week(end_date)-week(start_date)) as total_course_days
from Schedule) t1
JOIN
(select count(attend_dt) as total_attendance,student_id,schedule_id
from course_attendance group by student_id, schedule_id) t2
ON t1.schedule_id=t2.schedule_id
JOIN
student s
ON t2.student_id=s.id;
Here is the result set ( the attendance_rate is not nice due to the abridged course_attendance table):
student_id, name, course_id, attendance_rate
2, Cecilia, 1, 15.3846
6, Harry, 1, 10.2564
1, Jonny, 3, 15.3846

How to select average of two colums with same foreign key

I have a table of matches of a game in a tournement.
Here is the mysql table:
id
player1
player1_score
player1_rating
player2
player2_score
player2_rating
tourney_id
round
1
1
9
1.05
2
3
5.34
5
1
2
3
4
5.21
4
9
3.34
5
1
3
5
9
3.52
6
2
5.24
5
1
4
1
9
6.23
3
0
4.74
5
2
5
2
8
9.43
4
9
1.23
5
2
6
3
9
3.41
5
7
6.23
5
2
7
1
9
5.22
4
2
2.43
5
3
8
2
3
4.21
3
9
5.22
5
3
9
5
1
7.31
6
9
3.43
5
3
How can I get the average player ratings for each individual player in a particular tourney?
Please note, there's two columns with player ids (player1, player2)
Based on your requirements (Even though you do not give us your expected results), I assume your code should be like this:
SELECT (SELECT SUM(player1_rating) / COUNT(DISTINCT player1)
FROM your_table GROUP BY player1) as avg_player1,
(SELECT SUM(player2_rating) / COUNT(DISTINCT player2) FROM your_table
GROUP BY player2) as avg_player2
FROM your_table
I revised the query to:
SELECT player_id
, tourney_id
, avg_player_rating = SUM(player_rating) / SUM(cnt)
FROM (
SELECT player_id = player1
, tourney_id
, player_rating = SUM(player1_rating)
, cnt = COUNT(*)
FROM tournament
GROUP BY tourney_id, player1
UNION ALL
SELECT player_id = player2
, tourney_id
, player_rating = SUM(player2_rating)
, cnt = COUNT(*)
FROM tournament
GROUP BY tourney_id, player2
) AS a
GROUP BY player_id, tourney_id
and this will give the result:
player_id tourney_id avg_player_rating
---------- ---------- --------------------
1 5 4.1666
2 5 6.3266
3 5 4.6450
4 5 2.3333
5 5 5.6866
6 5 4.3350
I hope that this is the result that you are looking for.

mysql select 2 table based on date and combine each other

i Need some help.. i have some case like this below
i have 2 table.. call ("in_table" and "out_table")
data "in_table" look like
stock_id item_id date qty_in
-----------------------------------------
1 11 2017-07-11 12
2 11 2017-07-11 10
3 12 2017-07-11 10
4 12 2017-07-19 10
And i have "out_table" is like
id_tr item_id date qty_out
-------------------------------------
1 11 2017-07-19 2
1 12 2017-07-19 1
2 11 2017-07-19 2
2 12 2017-07-19 1
And i want to combine the date and display all the data like this,
Update: the join is by item_id but i want to select by date
date item_id qty_in qty_out
---------------------------------------
2013-07-11 11 22 0
2013-07-11 12 10 0
2013-07-19 11 0 4
2013-07-19 12 10 2
Thank you for your help.
It looks like you need kind of a full outer join of two aggregate subqueries. But in your case I would get item_id and date in a union subquery (derived table) and the sums in correlated subqueries (subselect).
select item_id, date,
(select sum(qty_in) from in_table i where i.item_id = sub.item_id and i.date = sub.date) as qty_in,
(select sum(qty_out) from out_table o where o.item_id = sub.item_id and o.date = sub.date) as qty_out
from (
select item_id, date from in_table
union
select item_id, date from out_table
) sub
order by date, item_id

resive max 2 result of value in column MyType

In my tables I've same date with different type (MyType). I wants to revive max. 2 result of each different MyType when Created (date) > 2017-04-10.
My Date:
ID MyType Created
1 A 2017-04-09
2 C 2017-04-09
3 D 2017-04-09
4 A 2017-04-12
5 A 2017-07-09
6 A 2017-11-08
7 C 2017-05-09
8 C 2017-09-12
9 C 2017-10-01
10 B 2017-04-09
11 D 2017-05-17
expected result:
ID MyType Created
4 A 2017-04-12
5 A 2017-07-09
7 C 2017-05-09
8 C 2017-09-12
11 D 2017-05-17
How to receive max 2 result of each MyType's column?
SELECT ID,
MyType,
CreatedDate
FROM
( Select ID,
MyType,
CreatedDate,
ROW_NUMBER() OVER (PARTITION BY ID Order by CreatedDate desc) [RN]
From YourTable) A
WHERE
A.RN IN (1,2)
ORDER BY
CreatedDate

Select the 2 latest records from table

I have data like in this mysql table:
id customer_id date price
1 A 2014-01-01 4
2 A 2014-02-01 3
3 B 2014-03-01 2.5
4 B 2014-04-01 1
5 B 2014-05-01 5
6 C 2014-06-01 2
7 D 2014-07-01 2
8 D 2014-08-01 2.5
9 D 2014-09-01 1
I want to get the latest two dates for customer_id A, B and D. My result should be like this:
id customer_id date price
1 A 2014-01-01 4
2 A 2014-02-01 3
4 B 2014-04-01 1
5 B 2014-05-01 5
8 D 2014-08-01 2.5
9 D 2014-09-01 1
Any help is greatly appreciated.
One possible way :
SELECT *
FROM test s
WHERE (
SELECT COUNT(*)
FROM test f
WHERE f.customer_id = s.customer_id AND
f.`date` >= s.`date`
) <= 2
AND customer_id in('A','B','D');
[SQL Fiddle demo]
Try like this
select * from table where customer_id in('A','B','D') order by date desc limit 2