SELECT different users from same table in single JOIN - mysql

I am currently trying to join a table (tasks) with another table (users). I need to select different rows from the users table based on values in the tasks table:
tasks(user1, user2, user3);
users(id, name, email);
Previously I have linked data using a LEFT JOIN like so:
SELECT * FROM tasks LEFT JOIN users ON tasks.user1 = users.id;
Thats pretty simple, so I have tried using an AND like so:
SELECT * FROM tasks LEFT JOIN users ON tasks.user1 = users.id AND tasks.user2 = users.id;
but that returns the users fields as NULL, which makes sense as tasks.user1 is different to tasks.user2
I am pretty stumped on how to do this now, all suggestions welcome!

You'll need to repeat the join and alias the users table diffeently for each joined column:
SELECT * FROM tasks
LEFT JOIN users u1 ON tasks.user1 = u1.id
LEFT JOIN users u2 ON tasks.user2 = u2.id
...

use this one:
SELECT *
FROM tasks
LEFT JOIN users
ON tasks.user1 = users.id
OR tasks.user2 = users.id;

Related

How to select two joined columns?

I have a table with two columns:
player1_id and player2_id - they are linked with id's in users table (primary key)
I am trying to select users name using their id's with query below but it gives me two rows instead of one
SELECT users.name, tournaments_results.* FROM tournaments_results JOIN users ON tournaments_results.p1_id = users.id
UNION
SELECT users.name, tournaments_results.* FROM tournaments_results JOIN users ON tournaments_results.p2_id = users.id
how to select users.name as two different columns as name_player_1 and name_player_2 accordingly in one row in result?
You use two joins:
SELECT tournaments_results.*, u1.name, u2.name
FROM tournaments_results tr LEFT JOIN
users u1
ON tr.p1_id = u1.id LEFT JOIN
users u2
ON tr.p2_id = u2.id;
This uses LEFT JOIN, in case one of the columns doesn't match.

getting common joins for every combination of entries from a table

I have a table of users with userid and username.
Another table has a list of interests, with interestid and name.
A third table is a join table, with userid and interestid.
For each pair of users, I want to get the count of interests they have in common. I've tried a lot of things, the most recent is this:
SELECT u1.username AS me, u2.username AS you, COUNT(j.interestid) AS commoninterests
FROM users u1, users u2
INNER JOIN interests_join j
ON u1.id = j.id
WHERE u1.id != u2.id
GROUP BY u1.name
I just can't get a working query on this. Any help?
This is a self join on interests_join:
select ij1.userid, ij2.userid, count(*)
from interests_join ij1 join
interests_join ij2
on ij1.interestid = ij2.interestid and
ij1.userid < ij2.userid
group by ij1.userid, ij2.userid;
Note: this version only brings back the ids and only one pair for two users: (a, b) but not (b, a).
Now, this gets trickier if you want to include user pairs that have no common interests. If so, you need to first generate the user pairs using a cross join and the bring in the interests:
select u1.username, u2.username, count(ij2.userid)
from users u1 cross join
users u2 left join
interests_join ij1
on ij1.userid = u1.userid left join
interests_join ij2
on ij2.userid = u2.userid and
ij1.interestid = ij2.interestid
group by u1.username, u2.username;

Join two tables query

I have two tables users and linkage. I am creating a link between one user to another. Means user A will be linked to user B and vise versa.
Now I want to get the details of linked users for a particular entered user_id. Means If user A is finding his linked Id's then the details of linked id's should be seen.
Linkage has three columns its id, user_id and linked_contact_id.
Users has columns as user_id, user_name,pass etc..
I tried one join but I only get the linked Id's from this not the details of id's.
SELECT * FROM Users INNER JOIN linkage ON linkage.user_id = Users.user_id WHERE linkage.linked_contact_id = 1
output
user_id linked_contact_id
1 4
1 1
1 5
How can I get this?Please help.. Thank you...
You will need to join on the users table a second time:
SELECT u.*, u2.* FROM Users u
INNER JOIN linkage l ON l.user_id = u.user_id
INNER JOIN Users u2 ON l.linked_contact_id = u2.user_id
WHERE l.linked_contact_id = 1
Please note that as you are selecting the same columns twice (in u.*, u2.*), you will probably have to list out each field with an alias to distinguish between them.
Something wrong on your ratio. But it's okay.
Try LEFT JOIN or RIGHT JOIN
SELECT * users
LEFT JOIN linkage
ON linkage.user_id = users.user_id
WHERE linkage.linked_contact_id = 1
Get Users information
SELECT users.*,
linkage.*,
contact.user_id as contact_user_id,
contact.user_name AS contact_user_name
FROM users
INNER JOIN linkage ON linkage.user_id = users.user_id
INNER JOIN users AS contact ON linkage.linked_contact_id = contact.user_id
WHERE linkage.linked_contact_id = 1
Edit
Here Screenshot of Query Output

MySQL LEFT JOIN with WHERE returns NULL

Trying to JOIN a few tables to supply the user some information on other users he subscribed to this session.
There is a list of other users with their pictures
this works:
SELECT DISTINCT profile_picupload.imageFull, goals_list.goal, goal03.other,
users.username, users.email FROM profile_picupload
JOIN anal_muses
ON anal_muses.username = profile_picupload.username
JOIN goal03 ON goal03.username = anal_muses.username
JOIN goals_list ON goal03.goal=goals_list.id
JOIN users ON users.email = anal_muses.username
it gives me the desired list.
But - i need the list from anal_muses for this session only - so i changed the code to this:
SELECT DISTINCT profile_picupload.imageFull, goals_list.goal, goal03.other,
users.username, users.email FROM profile_picupload
right JOIN anal_muses
ON anal_muses.username = profile_picupload.username
AND anal_muses.sessionId='$sessionId'
JOIN goal03 ON goal03.username = anal_muses.username
JOIN goals_list ON goal03.goal=goals_list.id
JOIN users ON users.email = anal_muses.username
table profile_picupload - holds only one picture for each user
while table anal_musers holds many rows for each user ( depends on the number of people he subscribed to)
so when i added AND anal_muses.sessionId='$sessionId' I needed to change the first join to RIGHT JOIN
but now i get a list with NULL values for profile_picupload .imageFull
.....
is there a way around this?
Thank you :-)

MySQL Join table and count distinct users with no reference in another table

I am trying to count users that are NOT referenced in another table... Right now, I have something along the lines of this:
SELECT COUNT(DISTINCT u.id) FROM users u INNER JOIN orders o ON o.assigned!=u.id;
However, it's returning an invalid value. Any suggestions?
Thank you!
I would suggest using a LEFT JOIN between the two tables and filter the rows without a matching id in the orders table:
select count(u.id)
from users u
left join orders o
on o.assigned = u.id
where o.assigned is null
See SQL Fiddle with Demo
Use a left join and count the rows with no match:
SELECT COUNT(*)
FROM users u
LEFT JOIN orders o
ON o.assigned = u.id
WHERE o.assigned IS NULL
An alternative is to use a NOT IN check:
SELECT COUNT(*)
FROM users
WHERE id NOT IN (SELECT distinct(assigned) FROM orders)
However, in my experience the left join performs better (assuming appropriate indexes).
Simply use this query, assuming that the id is unique in users table:
select count(*) From Users as u where u.id not in (select assigned from orders)
an inner join explicitly looks for rows that match so that isn't the way to go if you are looking for non matched records
assuming that ORDERS.ASSIGNED is matched with USER.ID an outer join could return values from both and show when there aren't matches like so
select
u.id,
o.*
from users u
full outer join orders o
on o.assigned = u.id;
if you only want to know which USER.ID don't have an ORDERS record you could also INTERSECT or use NOT IN () eg
select u.id from users u where id not in (select o.assigned from orders.o);
SELECT COUNT(1) FROM users u
WHERE NOT EXISTS (SELECT * FROM orders o WHERE o.assigned=u.id);
Are you wanting a straight count (like you mentioned), or do you need values returned? This will give you the count; if you want other values, you should take one of the other approaches listed above.