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
I want to answer the following question using the below Mysql tables.
How many days were the user active on avg. (had an action) in the last
week?
I want to Display user Avg by day,
where
((user action is not 0)/unique day) in the last 7 days.
0 means the user is not active and 1 means active.
I am still a newbie in SQL and here is what I have tried so far. I am not really sure of my answers.
SELECT u.username, COUNT(u.snapshot_date) as 'active_days', a.action
FROM actions a
JOIN users u
ON a.user_id = u.user_id
WHERE NOT (a.action = 0)
GROUP BY u.username;
my output
username active_days action
Albert 2 1
Paul 4 1
Ronaldo 2 1
Messi 1 1
users table
user_id username snapshot_date
1 Albert 2022-01-10
2 Paul 2022-01-10
3 Blessing 2022-01-10
4 Ronaldo 2022-01-22
5 Messi 2022-01-01
action table
action_id action snapshot_date user_id
1 0 2022-01-10 1
2 1 2022-01-10 2
3 0 2022-01-10 3
4 1 2022-01-22 4
5 1 2022-01-01 5
6 0 2022-01-10 2
7 0 2022-01-10 1
8 0 2022-01-10 3
9 0 2022-01-22 2
10 0 2022-01-01 4
11 0 2022-01-10 2
12 1 2022-01-10 1
13 0 2022-01-10 3
14 1 2022-01-22 2
15 1 2022-01-01 4
16 1 2022-01-10 2
17 1 2022-01-10 2
18 0 2022-01-10 1
19 1 2022-01-22 1
20 0 2022-01-01 5
Average of last week
Since there are 7 days, you can divide the count by 7
SELECT u.username, COUNT(u.snapshot_date) / 7 as active_days, 1 as action
FROM actions a
JOIN users u
ON a.user_id = u.user_id
WHERE NOT (a.action = 0)
GROUP BY u.username, u.snapshot_date;
For the second problem you can average the sum of action:
SELECT u.username, SUM(a.action) / 7 as action_days, 1 as action
FROM actions a
JOIN users u
ON a.user_id = u.user_id
WHERE NOT (a.action = 0)
GROUP BY u.username, u.snapshot_date;
I have 1 table called itemmovement : It has Item Id , Quantity In , Quantity Out , Invoice Id, Date. I need to make in one query to show how many pieces are sold and beside the sold column there will be the current on hand quantity .
itemmovement
Id itemid qtyin qtyout invid purchasereturnid date
1 1 10 2019-01-04
2 2 8 2019-01-06
3 2 2 1 2019-01-08
4 1 3 2 2019-01-12
5 2 1 2019-02-04
6 3 4 2019-03-04
7 1 1 3 2019-04-04
8 1 1 1 2019-04-14
9 3 1 2 2019-04-24
I need the query to show this result
Id itemid Sold Quantity OnHandQty
1 1 4 5
2 2 2 7
3 3 0 3
I'm Trying to use this query but not working
SELECT *
FROM
(SELECT itmv.itemid,
sum(itmv.qtyout)-sum(itmv.qtyin)
FROM itemmovement itmv
WHERE (itmv.systemdate BETWEEN '2019-01-01' AND '2019-06-01')
AND invid>0
GROUP BY itmv.itemid) AS result1,
(SELECT sum(itmv2.qtyin)-sum(itmv2.qtyout)
FROM itemmovement itmv2
WHERE itmv.itemid=itmv2.itemid
GROUP BY itmv2.itemid) AS result2
ORDER BY sum(itmv.qtyin)-sum(itmv.qtyout)
I'm getting :
Unknown column 'itmv.itemid' in 'where clause it for this syntax :
where itmv.itemid = itmv2.itemid
Here's your query.
select itemid
, sum(case when COALESCE(invid,0) > 0 then qtyout else 0 end) as Sold_Qantity
, sum(qtyin)-sum(qtyout) as OnHandQty
from itemmovement
group by itemid
I have one table named viewlist as follows
Id article_id viewdate
--------------------------------------------------
1 1 2015-07-01
2 1 2015-07-01
3 1 2015-07-01
4 2 2015-07-01
5 2 2015-07-01
6 1 2015-07-02
7 2 2015-07-02
8 1 2015-07-03
9 2 2015-07-03
10 1 2015-07-05
11 1 2015-07-05
----------------------------------------------------
i need to write a MySQL query to get count and article_id by grouping adjacent viewdate field
wanted result as follows
article_id count date_period
-----------------------------------------------------------------
1 4 2015-07-01 - 2015-07-02
2 3 2015-07-01 - 2015-07-02
1 1 2015-07-03 - 2015-07-04
2 1 2015-07-03 - 2015-07-04
1 2 2015-07-05 - 2015-07-06
Is there any simple query to get this type of result?
you may use something on these lines
SELECT v.article_id, COUNT(*), CONCAT(b.dt, ' - ', b.dt2) as 'date_period'
FROM viewlist v INNER JOIN
(SELECT a.dt, DATE_ADD(a.dt, INTERVAL 1 DAY) AS dt2 FROM (SELECT DISTINCT(viewdate) AS dt FROM viewlist WHERE (DAY(viewdate) MOD 2) = 1) a) b ON v.viewdate BETWEEN b.dt AND b.dt2
GROUP BY 1, 3
ORDER BY b.dt
I have a "members" table like this:
id status user_id created_at
-----------------------------------
1 active 1 2015-07-01
2 active 2 2015-07-01
3 inactive 1 2015-07-04
4 deleted 2 2015-07-04
5 active 3 2015-07-04
6 active 1 2015-07-08
7 inactive 3 2015-07-08
How is it possible to query the latest status of all users at any given date?
For 2015-07-01 the output should be:
id status user_id created_at
-----------------------------------
1 active 1 2015-07-01
2 active 2 2015-07-01
For 2015-07-05 the output should be:
id status user_id created_at
-----------------------------------
3 inactive 1 2015-07-04
4 deleted 2 2015-07-04
5 active 3 2015-07-04
For 2015-07-10 the output should be:
id status user_id created_at
-----------------------------------
3 active 1 2015-07-08
4 deleted 2 2015-07-04
5 inactive 3 2015-07-08
Any help very much appreciated!
Use a group by with where to get the latest date before the given date, then a join:
select m.*
from members m join
(select user_id, max(created_at) as maxca
from members
where created_at <= '2015-07-08' -- or whatever
group by user_id
) mu
on m.user_id = mu.user_id and m.created_at = mu.maxca;