Could you guys help me to make SELECT query for my simple case:
Table A:
UserID UserName
10 John
11 Mike
12 Matt
Table B:
SessionID UserID SessionTime
124 10 20
123 10 122
42 10 30
324 11 55
534 11 42
344 12 19
653 12 32
I need this result:
Result Table:
UserName UserID TotalTime
John 10 172
Mike 11 97
Matt 12 51
For one Table B this works:
SELECT UserID, SUM(SessionTime) AS "Total Time"
FROM TableB
GROUP BY UserID;
but I need to attach UserName to the final result
thank you
You can do that by using join and group by:
select a.UserId, a.UserName, sum(b.SessionTime) as TotalTime
from tableA a
left join tableB b on a.UserId = b.UserId
group by a.UserId, a.UserName;
Note: This would work for 1-to-many relations as in your case.
SELECT TableA.Username, TableA.User_ID, SUM(SessionTime) INNER JOIN
TableB ON TableA.User_ID = TableB.User_ID GROUP BY TableA.Username,
TableA.User_ID
SELECT a.UserName as "UserName"
,a.UserID as "UserID"
,sum(b.SessionTime) as "TotalTime"
FROM a LEFT JOIN b
ON a.UserID = b.UserID GROUP BY a.UserID
Here. I used TABLE a and Table b
Related
(Using mysql 5.0)
I have this table:
opportunity main_user_id certificate_id required_certificates
1 491 1 2
1 341 1 2
1 161 1 2
1 161 2 2
1 205 2 2
1 578 2 2
2 161 2 2
2 466 3 2
2 466 2 2
2 156 2 2
2 668 2 2
3 222 5 1
3 123 5 1
3 875 5 1
3 348 5 1
I need to only display the rows where number of distinct values in certificate_id equals value in required_certificates.
opportunity_id column has id's from 0 to 15 and main_user_id's repeat (hence I can't use group by)
The table is basically a list of users matched for particular job opportunity, who have the required certificates. All i need to do now, is to only show the ones who have both of the required certificates, not one OR another.
My current sql statement:
select op_main.id as opportunity_id, u.id as main_user_id, c.id as certificate_id, required2.required as required_certificates
from opportunities as op_main
join opportunity_certificates as oc on oc.opportunity_id = op_main.id
join certificates as c on c.id = oc.certificate_id and oc.is_required
join user_certificates as uc on uc.certificate_id = c.id
join users as u on u.id = uc.user_id
join (
select id as op_id, (
select count(distinct c.id)
from opportunities as op
join opportunity_certificates as oc on oc.opportunity_id = op.id
join certificates as c on c.id = oc.certificate_id and oc.is_required
join user_certificates as uc on uc.certificate_id = c.id
join users as u on u.id = uc.user_id
where uc.certificate_id = oc.certificate_id and oc.is_required and op.id = op_id
) as required from opportunities
) as required2 on required2.op_id = op_main.id
where uc.certificate_id = oc.certificate_id and oc.is_required and op_id = op_main.id
based on the table above the output would be:
opportunity main_user_id
1 161
2 466
3 222
3 123
3 875
3 348
I spent many hours trying to work it out. If someone is keen on helping me, I can send you the database. Thanks.
It is quite simple with windowed functions - MySQL 8 and above:
WITH cte AS (
SELECT *, COUNT(DISTINCT certificate_id) OVER(PARTITION BY user_id) AS cnt
FROM (
-- your query with joins
) sub
)
SELECT *
FROM cte
WHERE cnt = required_certificates;
DBFiddle Demo
It turns out that MySQL 8.0 doesn't support COUNT(DISTINCT ...) OVER so I used subquery with DISTINCT.
ER_NOT_SUPPORTED_YET: This version of MySQL doesn't yet support '(DISTINCT ..)'
I have 2 table in my database. The first is comments and the other is comments_votes.
I want to select all comments, and for each comment, select all it's votes from comments_votes, add them up together and join it with the first query as totalVote.
My comments table look like:
id comment video_id date_sent
----------------------------------------
5 "...." 99 "2017-05-23"
18 "...." 99 "2017-05-23"
comments_votes table look like:
id user_id comment_id vote
----------------------------------------
45 86 5 1
45 23 5 1
78 12 18 -1
And the final wished result would look like:
id comment video_id votes_total
----------------------------------------
5 " ... " 99 2
18 "... " 99 -1
I can manage simple SQL operations but this is beyond me. Is something like this even possible? If yes, how?
select C.id, C.Comment, C.Video_ID, SUM(V.Votes) AS Vote_total
from comments C
left outer join comments_votes V
on C.id=V.comment_id
group by C.id, C.Comment, C.Video_ID
SELECT c.id,comment,c.video_id,SUM(v.vote) AS Vote_total
FROM comments c, comments_votes v
WHERE c.id = v.comment_id
GROUP BY C.id, C.Comment, C.Video_ID;
I have a table that looks like this:
id name yearofstudy mark
1 Alain A 2 75
2 Michael B 3 85
3 Chen C 1 55
4 Caroline D 2 60
5 Mohamed E 2 60
6 Alex F 1 55
7 Sofia O 3 78
8 Samir O 1 85
9 Rob G 2 78
10 Big K 3 55
And I'm trying to get the id, name, year and mark of the students with the lowest (and highest) mark in each year which would give:
id name yearofstudy mark
3 Chen C 1 55
4 Caroline D 2 60
10 Big K 3 55
SQL isn't my strong point and I've been trying using the MIN() function but I haven't managed to get it right yet and would really appreciate some help.
Using a subquery to get the min() and max() for each yearofstudy, and joining it to the original table. (You did say you wanted lowest and highest, right?)
select t.id, t.name, t.yearofstudy, t.mark
from t
inner join (
select
yearofstudy
, min(mark) as minMark
, max(mar) as maxMark
from t
group by yearofstudy
) as m
on t.yearofstudy = m.yearofstudy
and (t.mark = minMark or t.mark = maxMark)
or for just the lowest mark per year:
select t.id, t.name, t.yearofstudy, t.mark
from t
inner join (
select
yearofstudy
, min(mark) as minMark
from t
group by yearofstudy
) as m
on t.yearofstudy = m.yearofstudy
and t.mark = minMark
You could write the query as follows:
SELECT t1.* from your_table t1
INNER JOIN (
SELECT yearofstudy, MIN(marks) as marks
FROM your_table GROUP BY yearofstudy
) t2
ON t1.yearofstudy = t2.yearofstudy
AND t1.marks = t2.marks
GROUP BY t1.yearofstudy
ORDER BY t1.yearofstudy, t1.id;
If all the MIN records for the yearofstudy are required, then you could simply remove GROUP BY t1.yearofstudy
Demo
this is my query:
SELECT br.employee_id AS rat_id,
br.rating_comment,
br.created_at,
br.id
FROM employee_followers
LEFT JOIN employee_ratings AS br ON employee_followers. employee_id = br.employee_id
WHERE employee_followers.employee_id IN
(SELECT `employee_id`
FROM employee_followers
WHERE user_id =32)
GROUP BY br.id
ORDER BY created_at DESC
what I am getting:
rat_id rating_comment created_at id
18 superb developer 2016-02-19 18:26:54 82
9 james to manoj-joshi 2016-02-19 16:42:17 84
50 james to prem 2016-02-19 13:05:30 83
50 pinal to prem 2016-02-19 12:20:00 73
50 prem to premal-joshi 2016-02-19 11:40:52 78
18 prem to mukund 2016-02-19 11:21:52 77
18 pinal to mukund 2016-02-18 11:37:00 76
9 mukund rate to mitesh 2016-02-15 22:34:14 51
9 Not a bad. 2016-02-10 00:16:31 45
9 sda 2016-02-08 01:36:33 39
what I want:
rat_id rating_comment created_at id
18 superb developer 2016-02-19 18:26:54 82
9 james to manoj-joshi 2016-02-19 16:42:17 84
50 james to prem 2016-02-19 13:05:30 83
Try This
SELECT rat_id,rating_comment, MAX(created_at) AS created, id FROM (
SELECT br.employee_id AS rat_id,
br.rating_comment,
br.created_at,
br.id
FROM employee_followers
LEFT JOIN employee_ratings AS br ON employee_followers. employee_id = br.employee_id
WHERE employee_followers.employee_id IN
(SELECT `employee_id`
FROM employee_followers
WHERE user_id =32)
GROUP BY br.id
ORDER BY created_at DESC) AS temp GROUP BY temp.rat_id
It seems that you want only the latest record per employee_id. You can use a derived table to get the maximum date, then join again to get all fields from employee_ratings table for this date:
SELECT er.employee_id AS rat_id,
er.rating_comment,
er.created_at,
er.id
FROM employee_followers AS ef
LEFT JOIN (
SELECT employee_id, MAX(created_at) AS max_date
FROM employee_ratings
GROUP BY employee_id
) AS emp_max ON ef.employee_id = emp_max.employee_id
LEFT JOIN employee_ratings AS er
ON emp_max.employee_id = er.employee_id AND
emp_max.max_date = er.max_date
WHERE user_id = 32
ORDER BY created_at DESC
I have also removed GROUP BY br.id that seems to be redundant in the context of the query. Also IN operator can be replaced by user_id = 32 since you are selecting from the same table.
I have two tables. I want to select id from table 1 and count the same from table2
Table 1
Id qId opt
1 30 Chris Christie
2 30 Hillary Clinton
3 30 Allan West
4 30 Joe Biden
5 31 Mark
6 31 Ben Johnson
Table2
poll_id qId ansId
201 30 1
202 30 2
204 31 8
The below query i tried, outputs only the ansId 1 and 2 since there is no 3 and 4 in Table2.
SELECT a.Id,
a.opt,
COUNT(b.ansId)
from Table1 a
INNER JOIN Table2 b ON a.Id = b.ansId
where a.qId =30
But i need all ansId 1,2,3,4 with count of 3 and 4 as 0 as given below.
Id opt COUNT(b.ansId)
1 Chris Christie 1
2 Hillary Clinton 1
3 Allan West 0
4 Joe Biden 0
First thing your are missing with group by ,count is an aggregate function and this needs to be grouped,second you need to use left join with an additional condition in on clause i.e and a.qId =30 so it will stil gives you the result if left id is not found in right table,using where clause will filter out the whole resultset while if you use additional condition in join this will only filter the records from the right table
SELECT a.Id,
a.opt,
COUNT(b.ansId) from Table1 a
LEFT JOIN Table2 b ON a.Id = b.ansId and a.qId =30
GROUP BY a.Id
Fiddle Demo
Edit after sample dataset is updated
SELECT a.Id,
a.opt,
COUNT(b.ansId) from Table1 a
LEFT JOIN Table2 b ON a.Id = b.ansId
WHERE a.qId =30
GROUP BY a.Id
Fiddle demo 2