Filter joined results - mysql

Imagine the following table structure:
tb.user tb.usergroups tb.group
id id id
name user_id name
group_id
A user can be in multiple groups through the usergroups table.
I want to search for a user by user name and group name. Speaking in examples: user "Bob" is in "GroupA" and in "GroupB". My query so far:
SELECT *
FROM user u
JOIN usergroups ug ON ug.user_id = u.id
JOIN group g ON ug.group_id = g.id
WHERE u.name = 'Bob' AND g.name != 'GroupA'
This isn't exactly what I want; my result still contains Bob, since he's in "GroupB", but I don't want the result to contain Bob at all.
How to do that?
Thanks

I understand you want to select all users named "Bob" that are not in group A but are in group B. This should do it :
SELECT b.*
FROM (SELECT * FROM user u
JOIN usergroups ug ON ug.user_id = u.id
JOIN group g ON ug.group_id = g.id
WHERE u.name = 'Bob' AND g.name = 'GroupB') b
LEFT JOIN (SELECT userid FROM user u
JOIN usergroups ug ON ug.user_id = u.id
JOIN group g ON ug.group_id = g.id
WHERE u.name = 'Bob' AND g.name = 'GroupA') a
ON a.userid=b.userid
WHERE a.userid is NULL

Check this query as i understand you are looking something like this:
SELECT * FROM user AS u
LEFT JOIN usergroups AS ug ON u.id = ug.user_id
LEFT JOIN groups AS gp ON gp.id = ug.group_id
WHERE u.name = 'Bob'
GROUP by ug.user_id
HAVING count(ug.group_id) = 1 AND gp.name !="GROUPA"

Related

SQL query to find all users, User 'A' follows and then check if another User 'B' also follows the same users

I want to display all users data, who User 'A' is following. And then further check if User 'B' is also following some users of User 'A'.
I managed to get al users data, who User 'A' is following. But don't understand how to query for the second condition.
Here is my Fiddle link with an example: https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=29a7d1e29f794a8f18a89fe45c06eaa9
You can try to let your User 'B' in a subquery then do OUTER JOIN
SELECT u.*,
IF(friend_id IS NULL,0,1) amIfollowing
FROM users u
LEFT JOIN (
Select friend_id
from friends
where user_id = 5
) f ON f.friend_id = u.id
WHERE u.id IN (SELECT f.friend_id
FROM friends f
WHERE f.user_id = 1)
ORDER BY u.id
sqlfiddle
If I understand correctly you can try to use only one subquery for friends and then use the condition aggregate function to get the result.
SELECT u.id,
u.image_width,
MAX(CASE WHEN f.user_id = 5 THEN 1 ELSE 0 END) amIfollowing
FROM users u
JOIN (
Select friend_id,user_id
from friends
where user_id IN (1,5)
) f ON f.friend_id = u.id
GROUP BY u.id,
u.image_width
ORDER BY u.id
You could use exists here to check if the corresponding IDs exist:
SELECT *,
case when exists (
select * from friends f
where f.friend_id = u.id and f.user_id = 5
) then 1 else 0 end amIfollowing
FROM users u
WHERE u.id IN (SELECT f.friend_id
FROM friends f
WHERE f.user_id = 1);
Example Fiddle
Looks like a JOIN will do, with distinct
SELECT distinct u.*, (f2.user_Id is not null) amIfollowing
FROM users u
JOIN friends f ON u.id = f.friend_id
LEFT JOIN friends f2 on f2.friend_id = f.friend_id and f2.user_id = 5
WHERE f.user_id = 1
ORDER BY u.id

SQL displaying data from one table based on id from another table

I am new at SQL I a need help in creating one.
I have 2 tables:
table 1:
table2:
And now I want first name and last name for all friends of one user example of user John Doe based on id from user and friend user id from table friends?
You should do 2 joins, one to get each friend's ID and another to retrieve that friend's name.
SELECT
U.ID,
U.first_name,
U.last_name,
N.first_name FriendFirstName,
N.last_name FriendLastName
FROM
[user] U
LEFT JOIN firends F ON U.ID = F.user_id
LEFT JOIN [user] N ON F.friend_id = N.id
Using a LEFT JOIN will make you see people with no friends (sniff).
If you want to see a particular user:
SELECT
U.ID,
U.first_name,
U.last_name,
N.first_name FriendFirstName,
N.last_name FriendLastName
FROM
[user] U
LEFT JOIN firends F ON U.ID = F.user_id
LEFT JOIN [user] N ON F.friend_id = N.id
WHERE
U.ID = 1948 -- Supplied ID
Do the self joins
select f.first_name, u.first_name as friend_name
from user u
join (
select u.first_name, f.friend_id
from friend f
join user u on u.id = f.user_id
) f on f.friend_id = u.id
A simple inner join will do
Select First_name,Last_name
from user inner join friends on user.id = friends.user_id
where friends.id = 1
Or you can replace with friends.user_id = 1 if you would like to look at user_id column
maybe I'm getting it wrong, but this is my suggeston:
SELECT
u1.first_name,
u1.last_name,
u2.first_name AS FriendFirstName,
u2.last_name AS FriendLastName,
FROM user AS u1
INNER JOIN friends AS f
ON t1.id = f.user_id
INNER JOIN user AS u2
ON f.friend_id = u2.id

Fetching data in case of one -to- many relationship in MySQL

I have 3 tables users, user_group, and groups.
users have one to many relationship with groups.
If I want to fetch only those users who don't have group Mathematics.
I have using the following query for this purpose:
SELECT * FROM users
INNER JOIN user_group ON user_group.user_id = user.UserID
INNER JOIN groups ON user_group.group_id = groups.group_id
WHERE groups.Name <> 'Mathematics';
But it is returning multiple records against all Users. Suppose, if I have user John and he joined 3 groups Science, Mathematics and English. In this case, it will return two records of user John. I want to remove user John totally from the list.
You can use NOT EXISTS:
SELECT *
FROM users AS u
WHERE NOT EXISTS (SELECT 1
FROM user_group AS ug
INNER JOIN groups AS g ON ug.group_id = g.group_id
WHERE ug.user_id = u.UserID AND g.Name = 'Mathematics');
Demo here
If you want to do it using joins, then this is a way:
SELECT u.*
FROM users AS u
LEFT JOIN (
SELECT user_id
FROM user_group
INNER JOIN groups
ON user_group.group_id = groups.group_id AND groups.Name = 'Mathematics'
) AS g ON u.UserID = g.user_id
WHERE g.user_id IS NULL
Demo here
SELECT * FROM users
LEFT JOIN user_group ON user.UserID = user_group.user_id
LEFT JOIN groups ON user_group.group_id = groups.group_id
WHERE groups.Name != 'Mathematics';

Select two columns from two different table with multiple join[Mysql]

I have four tables are users(id,name), roles(id,name), members(project_id,user_id,id), and member_roles(member_id, role_id). So how can I select users.name and roles.name from this tables simultaneously(project_id is the condition to select exactly the names what we need)?. I can select users.name and roles.name separately but when I connect two queries, my code was failed. This is the query to get users.name
select users.name from users
inner join members on members.user_id = users.id
where project_id = 1
and here is the query to get roles.name
select roles.name from roles
inner join member_roles on member_roles.role_id = roles.id
join members on members.id = member_roles.member_id
where project_id = 1
You're almost there. Also, to avoid ambiguity, supply an Alias on column Name.
SELECT DISTINCT
u.Name AS member_name,
r.Name AS role_name
FROM users u
INNER JOIN members m
ON u.id = m.user_id
INNER JOIN member_roles mr
ON m.id = mr.member_id
INNER JOIN roles r
ON r.id = mr.role_id
WHERE m.project_id = 1
How do you connect 2 queries? How about something like this:
select u.name as user_name, r.name as role_name from users u join members m on m.user_id = u.id join member_roles mr on mr.member_id = m.id join roles r on r.id = mr.role_id where m.project_id = 1;

SQL - How to Query from 3 tables (query in query?)?

I want to know how to complete this query correctly.
I wish to export a full list of votes from all ips used by an user.
My database have 3 tables storing the relatives data =>
votes = vote_site_id | vote_ip | vote_time
connexions_ip = adresse_ip | user_id | connexion_time
users = user_id | user_name | user_ip
So actually I have this query to have all connexions_ip from one user =>
SELECT c.adresse_ip, c.user_id, u.user_name
FROM connexions_ip c
LEFT JOIN users u ON u.user_id = c.user_id
WHERE u.user_id = '1'
And this query to have all votes from one user =>
SELECT v.vote_site_id, v.vote_ip, v.vote_time, u.user_name
FROM votes v
LEFT JOIN users u ON u.user_ip = v.vote_ip
WHERE user_id = '1'
I tried with subquery but I have this error "#1242 - Subquery returns more than 1 row"
SELECT v.vote_site_id, v.vote_ip, v.vote_time, u.user_name
FROM votes v
LEFT JOIN users u ON (
SELECT c.adresse_ip
FROM connexions_ip c
LEFT JOIN users u ON u.user_id = c.user_id
WHERE u.user_id = '1'
)
= v.vote_ip
WHERE user_id = '1'
Thanks for your help.
You can join all the table
SELECT c.adresse_ip, c.user_id, u.user_name
, v.vote_site_id, v.vote_ip, v.vote_time
FROM users u
LEFT JOIN connexions_ip c ON u.user_id = c.user_id
LEFT JOIN votes v ON u.user_ip = v.vote_ip
WHERE u.user_id = '1'
I choosed the table users as the base for FROM because is the only table with a condition.
try this:
select a.*,b.* from (SELECT c.adresse_ip, c.user_id, u.user_name
FROM connexions_ip c
LEFT JOIN users u ON u.user_id = c.user_id
WHERE u.user_id = '1')a left join (SELECT u.user_id,v.vote_site_id, v.vote_ip, v.vote_time, u.user_name
FROM votes v
LEFT JOIN users u ON u.user_ip = v.vote_ip
WHERE user_id = '1')b on a.user_id = b.user_id