Join, Group By and Sum in MySQL - mysql

I have the following three tables in a MySQL database in order to give ratings to comments of users:
Users:
id name
-----------
1 Smith
2 Brown
Comments:
id user_id post_id comment
-----------------------------------
1 2 1 Test 1
2 1 1 Test 2
3 1 1 Test 3
Scores:
id user_id comment_id score
------------------------------------
1 1 1 1
Now I want to select all the comments for post_id = 1, plus the username and the sum of all the scores on that specific comment. At first it looks very simple, I came up with this query:
SELECT users.name, comments.comment, SUM(scores.score) AS score
FROM comments
LEFT JOIN users ON users.id = comments.user_id
LEFT JOIN scores ON scores.comment_id = comments.id
WHERE comments.post_id = 1
GROUP BY scores.comment_id
It seems to work, but when there isn't a score for a specific comment, the comment doesn't show up, because MySQL can't GROUP BY NULL, I guess. So, is there any way to include those unrated comments? Like this:
Query result:
name comment score
-------------------------
Brown Test 1 1
Smith Test 2 0
Smith Test 3 0

You could try grouping on comments.id instead perhaps?

Related

Left Join and remove duplicates

I have three tables, clients, job_allocations and jobs table. I want to select all clients that are not in a particular job, below are my tables.
Clients table
id
Fullname
1
John Doe
2
Jane Doe
3
King James
4
Jere Gray
Jobs table
id
Title
1
Road Construction
2
Repair of Engines
job_allocations table
id
client_id
job_id
1
2
1
2
2
2
3
1
2
4
3
2
I want to select all clients that are not in job_id=2, but when I ran my query, I am getting client id: 2 - Jane Doe again, please how do I solve this?
I did this:
LEFT JOIN job_allocations ON job_allocations.client_id = clients.id
WHERE job_id <> 2 OR job_id IS NULL```
You can use a NOT IN clause as follows:
SELECT *
FROM clients
WHERE id NOT IN (SELECT client_id
FROM job_allocations
WHERE job_id = 2)
Check the demo here.
So you will fetch all clients, but only jobs related to job_id <> 2
This query should work for you:
SELECT client.*
FROM clients
LEFT JOIN job_allocations ON job_allocations.client_id = clients.id and job_id <> 2
Use DISTINCT keyword for selecting unique values

MySQL join not producing expected results with 'in' function

I have a game_players table like this (other columns omitted for brevity):
game_id user_id
1 1
1 3
2 1
2 2
2 4
My intention is to show the user that's logged in only the games they're involved in (e.g. user 2 should only see game 2).
The "where 2 in(select game_players.user_id from game_players)" bit doesn't appear to be working, I get a list of all the games - including the ones user 2 isn't involved in.
select games.game_id as 'game_id',
games.date_game_started as 'date_started',
users.username as 'username',
users.permanent_id as 'permanent_id',
game_players.user_id as 'user_id'
from games
inner join game_players on games.game_id = game_players.game_id
inner join users on game_players.user_id = users.user_id
where 2 in(select game_players.user_id from game_players)
and games.game_active = 1
and game_players.current_turn = 1
group by(games.game_id)
order by field(game_players.user_id, 2) desc,
games.date_game_started asc
Given my test data, I get this result set:
game_id date_started username permanent_id user_id
1 2021-12-15 13:33:17 userc userc 3
2 2021-12-15 13:35:20 Admin admin 1
I should only be getting the second row, because user 2 is only involved in game 2.
I'll admit that my SQL is a bit rusty, please can you help?
I simplified/broke it down and found the answer. I think... so far so good on my testing of it.
Needed to change:
where 2 in(select game_players.user_id from game_players)
to...
where game_players.game_id in(select game_id from game_players where user_id = 2)

Select unique ids from multi values on one column in another table

I'm stuck for hours on an issue that might be pretty simple to solve but I'm just so lost...
I got 3 tables :
user
id name
----------
1 jack
2 john
...
car
id name
----------
1 ford
2 fiat
3 alfa
4 lada
...
user_car
id_user id_car
-----------------
1 2
1 4
2 1
2 2
2 3
For example, i want to get all users with cars which have id 1 AND 2 in the user_car table so I should get the id_user 2 only and I can't find the proper way to do it.
try this untested query:
select * from user join user_car car1 on id =car1.user_id
join user_car car2 on id =car2.user_id where car1.id_car=1 and car2.id_car=2
I would use UNION for this matter:
SELECT id as id_user from user where id in(1, 2)
UNION
SELECT id as id_car from car where id in (1, 2)
You can use COUNT to do this:-
SELECT user.name
FROM user
INNER JOIN user_car ON user.id = user_car.id_user
INNER JOIN car ON user_car.id_car = car.id
WHERE car.id IN (1,2)
GROUP BY user.name
HAVING COUNT(DISTINCT car.id) = 2
Note that this could be simplified to remove the need for the car table when you are just using the id of the car.
May be you want this
SELECT *
FROM USER
WHERE id IN
(SELECT id_user
FROM user_car
WHERE id_car=1 OR id_car=2);

MySQL Left join with count on second Table

I have looked through some of the other posts on this site and am not seeing exactly what im looking for so here goes.
Lets say i have 2 tables
juser
-----------------------------
userID firstName lastName
-----------------------------
1 billy bob
2 jezze belle
3 bobbie sue
and:
juserrel
---------------------------------------------
id userID relUserID state
---------------------------------------------
1 1 2 approved
2 2 1 retired
3 2 1 approved
4 3 2 approved
What i am trying to do is get a result set that shows each user info about each user in the juser table and adds a column called connections to the result set which shows how many "active" connections a particular user has to another user.
the result i expect based on the tables above is
resultSet
-----------------------------------------------
userID firstName lastName connections
-----------------------------------------------
1 billy bob 2
2 jezze belle 3
3 bobbie sue 1
The query I tried is as follows
select userID, firstName, lastName , coalesce(x.cnt,0) as connections
from juser
left outer join (select count(*) cnt from juserrel where juserrel.userID =
userID or juserrel.relatedUserID = userID and juserrel.state = 'approved')
x on userID = userID
The result set i get looks like this:
resultSet
-----------------------------------------------
userID firstName lastName connections
-----------------------------------------------
1 billy bob 4
2 jezze belle 4
3 bobbie sue 4
Help Please ;)
Try:
select u.userID, u.firstName, u.lastName,
count(case when ur.state = 'approved' then 1 end)
from juser u
inner join juserrel ur on u.userID = ur.userID or u.userID = ur.relUserID
group by u.userID, u.firstName, u.lastName
SQL Fiddle Example

MySQL three table join, find item's rating

I'm hoping this is an easy one for you gurus, but my SQL knowledge is failing me.
My sample dataset:
item
----
item_id item_name item_added
1 Apple <date_time>
2 Banana <date_time>
user
----
user_id user_name
1 Alice
2 Bob
3 Carol
rating
------
rating_id item_id user_id rating_value
1 1 1 3
2 1 2 4
3 1 3 5
4 2 1 5
5 2 2 2
I want to find out what rating all three users have given to a particular item. The output should include NULL for rating_value if the user hasn't rated the item. For example, if I have item_id 2, I'd like to get this output:
user_name item_name rating_value
Alice Banana 5
Bob Banana 2
Carol Banana NULL
I've tried all kinds of joins, but I just can't seem to figure this one out.
Many thanks in advance.
It looks like you want a cartesian product of user and item, which will then be joined with rating:
select user_name, item_name, rating_value
from user as u, item as i
left join rating as r
on r.user_id = u.user_id
and r.item_id = i.item_id
I haven't done any serious work with MySQL for 4.5 years, but this should do it.
Edit: Maybe MySQL requires AS for the table aliases.
select u.user_name, i.item_name, r.rating_value
from item i,user u
left join rating r
on r.user_id = u.user_id
and r.item_id = i.item_id
This should do the trick..