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;
Related
I have two tables representing users and their friends: users and friendships
users has id and name
friendships has id, friend1_id and friend2_id
By searching a user's name, I want to get their associated friends' names.
You can try this:
SELECT u2.name from users u1
INNER JOIN users u2 ON u1.name = [your_name_to_search]
INNER JOIN friendships fs
ON u2.id = fs.friend2_id AND u1.id = fs.friend1_id
Explanation:
I used 2 joins in this approach: the first users self join will assure you take the id corresponding to [your_name_to_search], and then the second join with friendships will extract the names of friend_2_id matching with the friend_1_id taken from the first join.
You can test this approach on this db-fiddle
Join friendships to 2 copies of users.
The 1st copy will be filtered for the user name that you search for and the 2nd will return all the user's friends:
select uf.name
from users u
inner join friendships fs on u.id in (fs.friend1_id, fs.friend2_id)
inner join users uf on uf.id in (fs.friend1_id, fs.friend2_id) and uf.id <> u.id
where u.name = ?
Replace ? with the name of the user whose friends you want in the results.
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
I need to build a complicated query and I don't even know where to start. Any help would be welcome.
I've got an users table and a games table with 2 Many to Many relationships between them, the tables and relevant columns are:
users: id
games: id
game_users_A: id, user_id, game_id. (A relationship)
game_users_B: id, user_id, game_id. (B relationship)
Let's say I chose an user and one of the relationships, for example user1, relationship A.
I want to get every other user and order them by how many games in their B relationships match the games in user1's A relationship.
Thanks. I've been trying to find similar questions but I don't even know how to call what I'm trying to do.
Edit.
Thanks to Hayden's help I was able to build the query I needed.
I just had to adapt his a little:
His query compares every user with each other. That is a lot more than I need to do, with around 3000 users it will return more than 900000 rows.
I only need to compare the user that's logged into my application with every other user in the database, so with N users I'll get N - 1 rows.
So I just added a couple of WHERE clouses and changed the ORDER BY.
Assuming the user making the request has an Id of 3 and wants to see the users matching the games in his A relationship with the games in their B relationship (and not the other way around), this is the query:
SELECT U1.id, U2.id, SUM(GCol) AS matches
FROM users U1 JOIN users U2 ON U1.id <> U2.id
LEFT JOIN (SELECT A.user_id AS A_id, B.user_id as B_id, (A.id IS NOT NULL) AS GCol
FROM game_users_A A JOIN game_users_B B
ON A.game_id = B.game_id AND A.user_id <> B.user_id WHERE A.user_id = 3) G
ON U1.id = G.A_id AND U2.id = G.B_id
WHERE U1.id = 3
GROUP BY GCol, U1.id, U2.id
ORDER BY matches desc
Thanks again.
I played around with a little test database with those tables, and here's what I have.
I broke it down into two queries. The first one was to match all users against all other users, which is simply:
SELECT U1.id, U2.id
FROM users U1 JOIN users U2 ON U1.id <> U2.id
ORDER BY U1.id, U2.id
The second query was to match up records in the B group to records in the A group, where the game is the same. This gave me:
SELECT A.user_id AS A_id, B.user_id as B_id
FROM game_users_A A JOIN game_users_B B
ON A.game_id = B.game_id AND A.user_id <> B.user_id
To combine these two, I did a left join of the first query against the second query, since for any pair of users, it's possible that there isn't a matching set of games. In these cases, the results of the second query will show up as NULL values. What we want is a value of 1 when those appear, so if you look in the query below, there's a value of
(A.id IS NOT NULL) AS GCol
which is used so we can find the sum. If there is a record, there's a value of 1, or NULL otherwise. When there are no values there, the total is still null, but when there are matches, the total is summed up and displayed. This gives a final query of:
SELECT U1.id, U2.id, SUM(GCol)
FROM users U1 JOIN users U2 ON U1.id <> U2.id
LEFT JOIN (SELECT A.user_id AS A_id, B.user_id as B_id, (A.id IS NOT NULL) AS GCol
FROM game_users_A A JOIN game_users_B B
ON A.game_id = B.game_id AND A.user_id <> B.user_id) G
ON U1.id = G.A_id AND U2.id = G.B_id
GROUP BY GCol, U1.id, U2.id
ORDER BY U1.id, U2.id
I think that's what you're looking for.
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;
So, the two tables in question:
userinfo: id(PK), users_id(FK to users table), name, surname
doctorpatient: id(PK), doctor_id(FK to users table), patient_id(FK to users table)
The idea is each doctor is assigned a few patients via the doctorpatient table. What I want to do is return an array of arrays, where each of the inner arrays contains this:
users_id(doctor), name(doctor), surname(doctor), users_id(patient), name(patient), surname(patient)
Can this even be done using purely SQL? I tried this:
SELECT userinfo.users_id,
userinfo.name,
userinfo.surname,
u2.users_id,
u2.name,
u2.surname
FROM doctorpatient
RIGHT OUTER JOIN userinfo
ON doctorpatient.doctor_id = userinfo.users_id
LEFT OUTER JOIN userinfo AS u2
ON doctorpatient.patient_id = u2.users_id
but no matter what combination of joins I try, it never comes out right. I tried getting the data in three separate queries and then somehow get the result I need using PHP, but I got nowhere with that.
Edit: What I want is this:
array(
subarray1(patient_id1,
patient_name1,
patient_surname1,
doctor_id1,
doctor_name1,
doctor_surname1)
subarray2(patient_id2,
patient_name2,
patient_surname2,
doctor_id1,
doctor_name1,
doctor_surname1)
etc...
where one doctor can have multiple patients. What my query gets me looks something like this:
array(
subarray1(patient_id1,
patient_name1,
patient_surname1,
)
subarray2(patient_id2,
patient_name2,
patient_surname2,
)
etc...
But most of the data is null.
I think a simple JOIN may be sufficient. The OUTER JOINs appear to be causing the null values because it tries to treat the doctors as patients.
SELECT u1.users_id AS doctor_id,
u1.name AS doctor_name,
u1.surname AS doctor_surname,
u2.users_id AS patient_id,
u2.name AS patient_name,
u2.surname AS patient_surname
FROM doctorpatient AS d JOIN userinfo AS u1 ON d.doctor_id = u1.users_id
JOIN userinfo AS u2 ON d.patient_id = u2.users_id
Try this:
SELECT
u.id as user_id,
u.name as user_name
u.surname as user_usrname
d.id as doc_id,
d.name as doc_name,
d.surname as doc_surname
FROM doctorpatient as dp
LEFT JOIN userinfo as u ON (dp.pacient_id = u.id)
LEFT JOIN userinfo as d ON (dp.doctor_id = d.id)