i have a tables like below
tableName: users
tableName: projects
tableName: user_project
So i want to get users who are not a part of project "1".
i tried like this but no luck
SELECT u.id, u.username
FROM testdb.user_project up
LEFT JOIN testdb.users u
ON up.userId = u.id
WHERE up.projectId=1 AND u.id IS NULL
My expected output
id | username
--------------
3 | u3
4 | u4
can you please help me out of this
Thank you in advance
The below query should work
select u.*
from users u
where u.id not in (select userId from user_project where projectId = 1)
use not exists
select u.* from users u
where not exists ( select 1 from user_project up
where up.userid= u.id and up.projectid=1)
Basically you want the users that are not associated with Project 1 in the relation table. You can do that using "where not exists".
The solution is better, cause exists removes the need to take care of duplicate values, cause one single occurrence is enough to match (or not match) the definition.
select
u.id
, u.username
from users u
where not exists (
select
1
from user_project up
where 1=1
and up.projectID = 1
and up.userId = u.id
)
SELECT u.id, u.username
FROM testdb.user_project up
LEFT JOIN testdb.users u
ON up.userId = u.id
WHERE up.projectId <> 1;
Related
I have three tables.
users, friends and communityusers tables.
I am trying to build a facebook like group system. User will try to search his/her friends from friend lists to add them to the group.
So here I am trying to remove those friends who are already added in the group. Here group users table is communityusers..
This is the structure of my communityusers table.
id | community_id | user_id
I am not being able to use this table with my current query.
SELECT f.id, u.id as user_id, u.userName, u.firstName, u.lastName, u.profilePic from friends f, users u
WHERE CASE
WHEN f.following_id=1
THEN f.follower_id = u.id
WHEN f.follower_id=1
THEN f.following_id = u.id
END
AND
f.status= 2
AND
(
u.firstName LIKE 's%' OR u.lastName LIKE 's%'
)
This query returns the friends lists of user id 1 now I want exclude users filtering from the communityusers table.
user_id from this query shouldn't be present in the communityusers table. How can I filter this from communityusers or third table?
Please let me know if question is not clear.
Any suggestion, idea and help would be highly appreciated.
Thank you so much.
Edit
After running the query I get
My communityusers table
See user_id = 2 is also selected from the above query. I want to remove the user_id = 2 from the result since it exists in the communityusers table.
I am trying to create a Fiddle but for some reason it's not working for me.
Thank you again.
#sadek
Simply use not in, in where condition
SELECT f.id, u.id as user_id, u.userName, u.firstName, u.lastName, u.profilePic
from friends f inner join users u on
CASE WHEN f.following_id=1 THEN f.follower_id = u.id WHEN f.follower_id=1 THEN f.following_id = u.id
END AND f.status= 2
where u.id not in (select distinct user_id from communityusers) and (u.firstName LIKE 's%' OR u.lastName LIKE 's%')
Try using left join with communityuser table by given condition cu.user_id is null - this will give you those users which are not in communituuser table
select a.* from
(SELECT f.id, u.id as user_id, u.userName, u.firstName, u.lastName, u.profilePic from friends f inner join users u
on CASE WHEN f.following_id=1 THEN f.follower_id = u.id WHEN f.follower_id=1 THEN f.following_id = u.id
END AND f.status= 2 where u.firstName LIKE 's%' OR u.lastName LIKE 's%')a
left join (select * from communityuser where community_id<>4) cu on a.user_id=cu.user_id
where cu.user_id is null
I have 2 tables table name is users and projects.the structure of table is:
user table
id | name | role
1 | samjad | user
2 | saneer | constructor
projects table
id | name | user_id | constructor_id |
1 | school | 1 | 2 |
How can i get all details from both table in a single row based on project table id.
i want to select
projectname username, constroctorname, user_id, constroctor_id
in a single row
You can join the user table twice - Once as users and then as constructors.
select p.name as projectname,
u.name as username,
c.name as contructorname,
p.user_id,
p.contructor_id
from projects p
left join user u on p.user_id = u.id
left join user c on p.contructor_id = c.id
where u.role = 'user' -- check if the said user has role "user"
and c.role = 'constructor'; -- check if the said constructor has role "constructor"
Do the fact you have two relation between project table and user (one for user and one for constroctor) You can use user joined for two time
select p.name, u1.username, u2.username, p.user_id, p.constroctor_id
from projects as p
inner join user as u1 on p.user_id = u1.id
inner join user as u2 on p.constroctor_id = u2.id
You can use concat() function:
SELECT CONCAT(field1, field2, field3);
https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_concat
or CONCAT_WS(separator,str1,str2,...)
Assuming there is a table called Constructor with columns name and constructor_id your query would be
select
p.name as projectname,
u.name as username,
c.name as constructorname,
u.id as userid,
c.id as constructorid
from
projects p
inner join user u on p.user_id=u.id
inner join constructor c on p.constructor_id=c.id
Use a join. You probably want an INNER JOIN:
SELECT * -- actually include only the fields you need
FROM Projects p
INNER JOIN Users u ON u.id = p.user_id
INNER JOIN Users uc ON uc.id = p.constructor_id
You'll want to join the tables on their keys. In this case something like the below:
select p.name as projectname
, u.name as username
, if(u.role='constructor',u.name,null) as constructorname
, p.user_id, p.constructor_id
from users u
join projects p
on p.user_id = u.id;
I have two tables as follows
user [ ID , username ]
relationship [ user1_id(FK) , user2_id (FK) , status ]
I am trying to get the username by using either user1_id or user2_id where the status = 1 from relationship table. user1_id and user2_id are both IDs from the user table. The following query is failing and I am not sure where it's going wrong.
SELECT
U.username,
(R.first_user_id, R.second_user_id AS friends)
FROM
user U,
`relationship` R
WHERE (R.`first_user_id` = {$userID} OR R.`second_user_id`)
AND (`status` = 1 AND U.ID = friends)
returns both names of users in a relationship with a status of 1.
this also assumes that if a relationship record exists, both users must be in the user table.
SELECT U1.UserName, U2.username
FROM Relationship R
INNER JOIN USER U1
on R.User1_ID = U1.user_ID
INNER JOIN USER U2
and R.User2_ID = U2.user_ID
WHERE R.Status=1
It looks like you may be trying to get the usernames of all users that have a relationship with a certain specified user, regardless of the order of user IDs in the relationship record. That could be this:
SELECT
U.username,
U.first_user_id,
FROM
user U
JOIN `relationship` R
ON R.first_user_id = U.ID
WHERE
(R.`second_user_id` = {$userID})
AND (`status` = 1)
UNION ALL
SELECT
U.username,
U.second_user_id,
FROM
user U
JOIN `relationship` R
ON R.second_user_id = U.ID
WHERE
(R.`first_user_id` = {$userID})
AND (`status` = 1)
If that produces duplicates (or could do) and you don't want it to do, then change the UNION ALL to a straight UNION.
I have succeeded based on xQbert answer:
SELECT
U1.username,
U2.username
AS user_friend
FROM
Relationship R
INNER JOIN
user U1
ON
R.first_user_id = U1.ID
INNER JOIN
user U2
ON
R.second_user_id = U2.ID
WHERE (R.`first_user_id` = {$userID} OR R.`second_user_id` = {$userID})
AND `status` = 1
I have 2 tables.
users(id,username) and links(id,usernameORid).
Example of rows: users{ [1,test] , [2,stack] } and links{ [1,overflow] , [2, 1] }
So, table links may contain username or id from table users. As you can see in the example,
usernameORid from links may not contain the id or username from users.
I hope you understood my example.
Now, i have this query:
SELECT l.usernameORid, u.username, u.id
FROM links l
LEFT JOIN users u
ON l.usernameORid= u.id
LEFT JOIN user_roles ur
ON ur.userID = u.id
WHERE ur.roleID < 4
group by u.id
But this query does not return rows from links if usernameORid is not an actual username or id from users.
In the previous example, will not return row [1,overflow]. I want that row too.
How can i achieve that?
EDIT: The problem is partialy related to
LEFT JOIN user_roles ur
ON ur.userID = u.id
WHERE ur.roleID < 4
but still, how can i achieve that?
user_roles ( id,userID,roleID)
Change your final WHERE condition to:
WHERE ur.roleID < 4 OR u.id IS NULL
This will allow it to return rows that didn't have a match in users. Normally a LEFT JOIN does that by itself, but since you're doing an additional join on that table, the WHERE clause is filtering those non-matching rows out because they don't have a roleID.
You can use an OR statement in your join between links and users. This will allow you to pick up users records where the link.usernameORid is equal to either the users.id or the users.username
SELECT l.usernameORid,
u.username,
u.id
FROM links l
LEFT JOIN users u ON
l.usernameORid = u.id OR
lusernameORid = u.username
LEFT JOIN user_roles ur
ON ur.userID = u.id
WHERE ur.roleID < 4
GROUP BY u.id
This will still cause records to drop if the found users->user_roles.roleID is less than 4. If you wanted to have link records maintained regardless of whether of a user was found by username or ID then you would need to subquery the users and user_roles table joins and apply your WHERE statement there instead. This query is below:
SELECT
l.usernameORid,
u.username,
u.id
FROM links l
LEFT JOIN
(
SELECT
users.username,
users.idusers
FROM
users
LEFT JOIN user_roles ON
user_roles.userID = users.id
WHERE
user_roles.roleID < 4
) u ON
l.usernameORid= u.id OR
l.usernameORid = u.username
group by u.id
Furthermore, if you wish the 2nd or 3rd column of your return to hold the value that is in l.usernameORid when the users table lacks a match... if your users.id is always numeric you could do some trickery with a CASE statement:
SELECT
l.usernameORid,
Coalesce(u.username, CASE WHEN .lusernameORid REGEXP '^[0-9]+$' THEN NULL ELSE l.usernameORid END) as username,
Coalesce(u.username, CASE WHEN .lusernameORid REGEXP '^[0-9]+$' THEN l.usernameORid ELSE NULL END) as userid
FROM links l
LEFT JOIN
(
SELECT
users.username,
users.idusers
FROM
users
LEFT JOIN user_roles ON
user_roles.userID = users.id
WHERE
user_roles.roleID < 4
) u ON
l.usernameORid= u.id OR
l.usernameORid = u.username
group by u.id
Keep in mind though, that if the users table doesn't have a match for the links.usernameORid then only the username OR the id could be determined, so you will have a NULL in one of the two fields.
I have two table, users and comments.
In the users table, there're columns id and username.
In the comments table I have user_id and his message.
And I wanted to create a table that select the username and his comment count when I search a particular username.
How do I write this?
my testing attempt:
SELECT COUNT(*) AS comment_count
FROM song_comments
RIGHT JOIN users
WHERE user_id = 7 AND comments.user_id = users.id
Try this:
SELECT U.Username, COUNT(SC.message) AS comment_count
FROM song_comments SC JOIN
users U ON U.id=SC.user_id
WHERE U.user_id = 7
GROUP BY U.Username
This gives you users and count
select u.username, count(c.user_id) as comment_count
from users u
join comments c on u.id = c.user_id
group by u.username
You can add a where to get one user's count
select u.username, count(c.user_id) as comment_count
from users u
join comments c on u.id = c.user_id
where u.username = 'Hogan'
group by u.username