Mysql database selecting with relation - mysql

I have this table that I hold userlist for my msn application. There's another table for the friendship where it has two foreign keys from userlist.
user: id, name, online, ip...
friend: id1, id2
I want the information of the users that are friend with a specific id.
I'm using this sql query:
SELECT (latest_ip, email, online, pass, status)
from im.user JOIN im.friend ON user.id = friend.id1
WHERE user.id = 5
what am i missing?

remove the parenthesis on your select clause, you don't need them
SELECT latest_ip, email, online, pass, status
from im.user
INNER JOIN im.friend
ON user.id = friend.id1
WHERE user.id = 5
UPDATE 1
you need to have extra join with the table user again since you want to get the informations of the user's friends.
SELECT c.*
from im.user a
INNER JOIN im.friend b
ON a.id = b.id1
INNER JOIN im.user c
ON b.id2 = c.id
WHERE a.id = 5

Related

MySQL query that selects non-friends of a user

I have the following schema of a Mysql database:
User(Id, FirstName, LastName, NickName, Etc.)
Request(SenderId, ReceiverId)
Friendship(Id1, Id2)
I consider friendship to be an undirected relation, which means that for every friendship, I insert it twice to the Friendship table. (Let me know if this is not a good idea, please).
What I am trying to retrieve is a list of users, who are not friends to a specific user (let me name him UserX), nor have a current request ongoing to/from him.
My initial trials led me to this:
SELECT User.Id, User.NickName, User.Picture FROM User
LEFT JOIN Friendship A ON User.Id = A.Id1
LEFT JOIN Friendship B ON User.Id = B.Id2
LEFT JOIN Request C ON User.Id = C.Sender
LEFT JOIN Request D ON User.Id = D.Reciever
WHERE User.Id <> ?
And, of course the placeholder is UserX's Id.
This doesn't work because, although the tuples that has friendships or requests with UserX are eliminated, The friends still appear because they have friendships with other users!
Thanks in advance.
If you want an efficient solution, use not exists multiple times:
select u.*
from user u
where not exists (select 1 from friendship f where f.id1 = u.id and f.id2 = ?) and
not exists (select 1 from friendship f where f.id2 = u.id and f.id1 = ?) and
not exists (select 1 from request r where r.SenderId = u.id and r.ReceiverId = ?) and
not exists (select 1 from request r where r.ReceiverId = u.id and r.SenderId = ?);
In particular, this can take advantage of indexes on:
friendship(id1, id2)
friendship(id2, id1)
request(SenderId, ReceiverId)
request(ReceiverId, SenderId)
This should have much better performance than solutions that union subqueries together.
Using a left join to a union list:
select *
from User u1
left join
(
select ID2 as id
from Friendships
where ID1 = 'UserX'
union all
select ID1
from Friendships
where ID2 = 'UserX'
union all
select Sender
from Request
where Receiver = 'UserX'
union all
select Receiver
from Request
where Sender = 'UserX'
) ux
on ux.id = u1.id
where ux.id is null
and ux.id <> 'UserX'
What if you collect all distinct IDs from table "request" and "Friendship" and then select records from Users ID not available in the above list.
SELECT Id, FirstName, LastName, NickName
FROM User
WHERE ID NOT IN
(
SELECT DSTINCT Id1 ID FROM Friendship
UNION
SELECT DSTINCT Id2 FROM Friendship
UNION
SELECT DSTINCT SenderId FROM Request
UNION
SELECT DSTINCT ReceiverId FROM Request
)A

How to select fields from three different tables in MySQL

This is driving me crazy, i've spent hours in this and i just don't know what to do:
i have 3 tables:
users
companies
company_permissions
in users i have coduser and username
in companies codcompany and company_name
and in company_permissions i have idcompany_permissions, codcompany, coduser
what i want to do is basically, with one query, get the name of the company to which the given username has permissions to access.
i had this query:
select users.coduser, users.username, companies.company_name
from users
inner join company_permissions on users.coduser = company_permissions.coduser
inner join companies on companies.codcompany = company_permissions.codcompany
where users.username = 'test'
But it doesn't return anything :C (it did at one point but now it doesn't do it)
there is no error with your query
check the database if the user 'test' exists
if it's exist because you using inner join it must be records in all three tables
check them again
I think for this case, you should use LEFT JOIN instead of INNER JOIN.
Anyway, WHERE users.user = 'test', I guest the field must be username.
Test your statement step by step
1.)
select users.* from users
--inner join company_permissions on users.coduser = company_permissions.coduser
--inner join companies on companies.codcompany = company_permissions.codcompany
where users.username = 'test'
is there a result... user-data is exist
2.)
select users.*
from users
inner join company_permissions on users.coduser = company_permissions.coduser
--inner join companies on companies.codcompany = company_permissions.codcompany
where users.username = 'test'
is there a result... the join between company_permissions and users is ok (data exist)
3.)
select users.*
from users
--inner join company_permissions on users.coduser = company_permissions.coduser
inner join companies on companies.codcompany = company_permissions.codcompany
where users.username = 'test'
is there a result the join between companies and company_permissions is ok..

Complex MySQL query with multiple select statements

I have three tables in Mysql that are link together:
Profile (ID, Name, Stuff..)
Contact(ID, ProfileID,desc,Ord)
Address(ID,ProfileID, desc, Ord)
Now I need to select all profile from the profile table, with the “desc” field from Contact and Address where Ord = 1. (this is for a search function where in a table I’ll display the name, main contact info and main Address of a client.
I can currently do this with three separate SQL request:
SELECT Name, ID FROM Profile WHERE name=”bla”
Then in a foreach loop, I’ll run the other two requests:
SELECT ProfileID, desc FROM Contact WHERE ProfileID=MyProfileID AND Ord=1
SELECT ProfileID, desc FROM Address WHERE ProfileID=MyProfileID AND Ord=1
I know you can do multiple SELECT in one query, is there a way I could group all three SELECT into one query?
You should be able to JOIN the tables on the profile.id and the profileid in the other tables.
If you are sure the profileid exists in all three tables, then you can use an INNER JOIN. The INNER JOIN returns matching rows in all of the tables:
select p.id,
p.name,
c.desc ContactDesc,
a.desc AddressDesc
from profile p
inner join contact c
on p.id = c.profileid
inner join address a
on p.id = a.profileid
where p.name = 'bla'
and c.ord = 1
and a.ord = 1
If you are not sure that you will have matching rows, then you can use a LEFT JOIN:
select p.id,
p.name,
c.desc ContactDesc,
a.desc AddressDesc
from profile p
left join contact c
on p.id = c.profileid
and c.ord = 1
left join address a
on p.id = a.profileid
and a.ord = 1
where p.name = 'bla'
If you need help learning JOIN syntax, here is a great visual explanation of joins
This query below only selects column when an ID from Profile table has atleast one match on tables: Contact and Address. If one or both of them are nullable, use LEFT JOIN instead of INNER JOIN because LEFT JOIN displays all records from the Left-hand side table regardless if it has a match on other tables or not.
SELECT a.*,
b.desc as BDESC,
c.desc as CDESC
FROM Profile a
INNER JOIN Contact b
ON a.ID = b.ProfileID
INNER JOIN Address c
ON a.ID = c.ProfileID
WHERE b.ORD = 1 AND
c.ORD = 1 AND
a.Name = 'nameHERE'
The LEFT JOIN version:
SELECT a.*,
b.desc as BDESC,
c.desc as CDESC
FROM Profile a
INNER JOIN Contact b
ON a.ID = b.ProfileID AND b.ORD = 1
INNER JOIN Address c
ON a.ID = c.ProfileID AND c.ORD = 1
WHERE a.Name = 'nameHERE'
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins
i have created working demo as your requirement :
The query bellow will retrieve all matching records from the database.its retrieving profile id,name stufff and description of contact tables
select p.id,p.name,p.stauff,c.descr,a.descr from profile as p
inner join contact as c on c.profileid=p.id
inner join address as a on a.profileid=p.id
where p.name="bla" and c.ord=1 and a.ord=1

SQL - Join two tables

I have two tables
Users: (id, name)
Relations: (user_id, relation_id)
User_id and relation_id are both ids from the table users.
What I want is ro recover all users who are friend with a specific user.
And here is my sql command: that doesn't work:
SELECT *
FROM users
NATURAL JOIN relations
WHERE user_id IN (SELECT id FROM users WHERE name='John doe');
Could you help me?
SELECT users.*
FROM relations
INNER JOIN users
ON relations.relation_id = users.id
WHERE relations.user_id = 12345;
You can also get the id with a subquery, just as you did in your example:
WHERE relations.user_id IN (SELECT id FROM users WHERE name='John doe');
To get all the relations a person has , the following query will work..
SELECT * FROM users us JOIN relations re ON us.id = re.relation_id
WHERE re.user_id = (
SELECT id
FROM users
WHERE name = 'John doe'
)
Try this
SELECT * FROM users as a
JOIN relations as b on a.id = b.user_id
WHERE b.user_id IN (SELECT id FROM users WHERE name='John doe')
SELECT user_id
FROM relations re
JOIN users us
ON us.id = re.user_id
WHERE relation_id = (
SELECT id
FROM users
WHERE name = 'John Doe'
)
Side note: you can't use NATURAL JOIN here, 'cause there is no column that have the same name and type in the two tables.
isnt this just a matter of querying the relations tables by the userId you are looking for?
select *
from relations
where user_id = #IdYouArelookingFor or relation_id = #IdYouArelookingFor
SELECT friend.*
FROM users AS friend
JOIN relations AS r
ON r.relation_id = friend.id
JOIN users AS u
ON u.id = r.user_id
WHERE u.name = 'John doe' ;
Friends are people with the same relation_id?
SELECT a.name FROM users a JOIN relations b on a.id = b.user_id
WHERE b.relation_id in
(select relation_id from relations where id = 'userid of user you are looking for')
AND a.id != 'userid of user you are looking for'
If your logic is different pls tell how it is working

Join two tables and display the details

I have two table.
1st table:
Table Name: User
-id
-name
2nd table:
Table Name: Record
-player1ID
-player2ID
-player3ID
-location
-time
I would like to display all records.
I use "SELECT * FROM Record"
However, I would like to display not the player ID, I want to display the name of the player. How can I write a SQL that can do so? Thanks.
You need an INNER JOIN.
The trick is to join the User table multiple times (under different aliases) because you need multiple values from it.
select u1.name as player1, u2.name as player2, u3.name as player3, r.location, r.time
from Record r
inner join User u1 on r.player1ID = u1.id
inner join User u2 on r.player2ID = u2.id
inner join User u3 on r.player3ID = u3.id
It appears you wish to have the 'record' table with names substituted in for the IDs?
In that case you can JOIN the User table to the Record table (read up about joins here):
SELECT u.name as player1, u2.name as player2, u3.name as player3,
r.location, r.time
FROM Record r
JOIN User u ON u.id=player1ID
JOIN User u2 ON u2.id=player2ID
JOIN User u3 ON u3.id=player3ID
select a.name, b.name, c.name, d.location, d.time from Record d, User a, User b, User c where d.player1Id=a.id && d.player2ID = b.id && d.player3ID = c.id;