Can you left and right join in mysql - php

I need 3 tables that are all relevant to the same thing.
For instance, 1 has user information, 1 has page information for that user and the other has page options for that user.
all connected through user_id
is is possible to do this.
SELECT *
FROM users
LEFT JOIN page_info ON users.id=page_info.user_id
RIGHT JOIN page_settings ON user.id=page_settings.user_id
WHERE users.id=$id
or will i be defeated to using 2 queries
Thanks

I think you misunderstand what a LEFT and RIGHT outer join do: read A Visual Explanation of SQL Joins.
In your case, with the users table coming first (i.e. to the "left" of all others), I suspect you want both joins to be LEFT outer joins? That is:
SELECT *
FROM users
LEFT JOIN page_info ON users.id = page_info.user_id
LEFT JOIN page_settings ON users.id = page_settings.user_id
WHERE users.id = $id

Yes, you can.
http://dev.mysql.com/doc/refman/5.0/en/join.html

Related

Mysql request SELECT with LEFT JOIN

I am a beginner in MySQL, I had some courses in mysql that are now finished, I have a homework , provided by our teacher, to make for my training but I block to retrieve data from the base for a social network site. I understand the basis of JOIN but I still have trouble understanding the logic of LEFT JOIN OR OTHER type INNER JOIN ...
Here is my problem, I have a database with 2 tables,
member(id_member*, login, photo)
friend(id_member_request*, id_member_accept*, accept, date_acceptation)
The accept field of the friend table is a field that allows me to validate if they have friends by setting the value to 1 instead of 0.
The fields id_member_request and id_member_accept agree to the id_member of the member table.
I want to retrieve the login and the picture of the members who are friends, to be able to display them then.
I tested several queries:
SELECT m.login
, m.photo
FROM friend AS a
LEFT
JOIN member AS m
ON m.id_member = a.id_member_accept
LEFT
JOIN member AS m1
ON m1.id_member = a.id_member_request
WHERE accept = 1;
The query works but does not show all friendly members and even several times some people.
In RIGHT JOIN The result is NULL.
In INNER JOIN no result.
Thanks in advance because I blocked for several hours and I confess to lose myself a little. ;-)
Formatting the statement will help you :)
Okay, so you are joining the same column on both m and m1.
The following will bring back the data, but you have to pass in id_member_request..
DECLARE INT #MEMBERID = 2; --Example ID
SELECT m.login, m.photo
FROM friend AS a
LEFT JOIN member AS m ON m.id_member = a.id_member_accept
WHERE a.id_member_request = #MEMBERID
AND a.accept = 1;
This is bring back the m.login, m.photo for all of the friends for the Member with the ID #MEMBERID;
I think you want the friends of person who logged in. means for particular Member_Id here is query that will help you
select * from friend a
inner join member b on (a.id_member_request=b.id_member or a.id_member_accept=b.id_member) and b.id_member=1
where accept=1
where 1 is a member id whose friends will be displayed
You could re-write your query as in the below example
SELECT `m`.`id_member` AS `memberID`,
`m`.`login` AS `memberLoginName`,
`m`.`photo` AS `memberPhoto`,
`m1`.`id_member` AS `friendID`,
`m1`.`login` AS `friendLoginName`,
`m1`.`photo` AS `friendPhoto`,
`a`.`accept_date` AS `acceptDate`
FROM `friends` AS `a`
INNER JOIN `member` AS `m` ON `a`.`id_member_request` = `m`.`id_member`
INNER JOIN `member` AS `m1` ON `a`.`id_member_accept` = `m1`.`id_member`
WHERE `a`.`accept`=1
ORDER BY `a`.`id_member_request`,`a`.`id_member_accept` ASC
View this example in SQL fiddle
Thanks a lot for your help ;-)
I've tried all your answers and with a little change, this one works fine even in INNER, LEFT, RIGHT JOIN...
SELECT login,photo
FROM friend AS a
INNER JOIN member AS m ON ( a.id_member_request = m.id_member
OR a.id_member_accept = m.id_member )
WHERE m.id_member !=$id_member
AND a.accept=1;

Limit LEFT JOIN results to 1 with flexible where clause

my query looks like that:
SELECT
count(users.id)
FROM users
LEFT JOIN mail_sender_jobs_actions ON mail_sender_jobs_actions.userID = users.id
LEFT JOIN table2 ON table2.userID = users.id
LEFT JOIN table3 ON table3.userID = users.id
WHERE {$flexibleWhereClause}
Now, the mail_sender_jobs_actions table CAN (doesnt need to return anything) return multiple entries. I dont want to group the results but still limit the returns of mail_sender_jobs_actions to 1 so I dont get duplicates... Otherwise the count wouldnt work properly.
Scraped the whole web and found nothing working for me as I want to keep the where clause flexible. Any solution?
EDIT
so to explain the situation. We have a table with users (users). We have a table with actions (mail_seder_jobs_actions). We have other tables related to that query which are not relevant (table1, table2, table3)
If a user does an action, an entry is being created in the actions table.
The where clause is flexible, meaning it is possible that somebody wants to only show users with a specific action.
It is also possible that an action is not relevant to the user, so this entry gets ignored.
With where criteria you have there is no point using left join, since the where criteria applies to the table on the right hand side, effectively turning the left join into an inner join.
Apparently yo do not use any columns from the right hand side table, so instead of using joins, I would use an exists subquery.
SELECT
1 as count,
users.email
FROM users
WHERE EXISTS (SELECT 1
FROM mail_sender_jobs_actions
WHERE mail_sender_jobs_actions.userID = users.id
AND mail_sender_jobs_actions.type = '1'
AND mail_sender_jobs_actions.jobID = '106'
AND {$flexibleWhereClause})
However, there is little point in having the count() because it will always return 1. If you want to count how many records each user has in the mail_sender_jobs_actions table, then you have to use left join, group by, and move the where criteria into the join condition:
SELECT
count(mail_sender_jobs_actions.userID),
users.email
FROM users
LEFT JOIN mail_sender_jobs_actions ON mail_sender_jobs_actions.userID = users.id
AND mail_sender_jobs_actions.type = '1'
AND mail_sender_jobs_actions.jobID = '106'
AND {$flexibleWhereClause}
GROUP BY users.email

MySQL Query 2 Tables in 1

I am having a problem writing a MySQL query to get data from 2 tables in the same database. I don't know how to combine the 2 tables into 1 table basically so that I can use PHP to display the information. Right now I am using 2 queries and PHP to join them... I really need the persons name and the score they got.
tbl_scores
----------
user_id
points
tbl_users
---------
user_id
name
tbl_users has more fields but those are the only ones that matter I think? Please help or send what I need to look up to learn more.
SELECT * FROM tbl_scores RIGHT JOIN tbl_users ON tbl_scores.user_id = tbl_users.user_id;
The word you're looking to use is JOIN... more information on MySQL JOINs can be found all over the internet but I found one here: http://mysqljoin.com/
The following code is untested but should work for your scenario...
SELECT
u.name,
s.points
FROM
tbl_users AS u LEFT JOIN tbl_scores AS s ON u.user_id = s.user_id
use Join and more specificaly Left Join because it returns all rows from the left table (tbl_users ), even if there are no matches in the right table (tbl_scores) so that you get all users even those with no score :
SELECT * FROM tbl_users LEFT JOIN tbl_scores ON
tbl_users.user_id = tbl_scores.user_id;

SQL Joins across multiple tables

I am building an online survey system for which I wish to produce statistics. I want query based on the gender of the user. I have the following tables:
survey_question_options
survey_answer
users
I have constructed the following query so that it brings back a null response where there are no answers to the question:
SELECT COUNT(sa.option_id) AS answer , so.option_label
FROM survey_answer sa
RIGHT JOIN survey_question_options so
ON sa.option_id = so.option_id AND
sa.record_date>='2011-09-01' AND
sa.record_date<='2012-08-01'
LEFT JOIN users u
ON (sa.uid = u.uid AND u.gender='F')
WHERE so.question_id=24
GROUP BY so.option_label
ORDER BY so.option_id ASC
My query returns the following results set:
0 Red
1 Yellow
0 Blue
0 Green
However, the gender condition in the LEFT JOIN appears to be ignored in the query. When I change the gender to 'M' the same result is returned. However, the expected result would be 0 for everything.
I am not sure where I am going wrong. Please help.
Thanks in advance.
Well, you are doing a COUNT on a column from the main table, so the gender condition on the LEFT JOIN won't affect the result. You should do the COUNT on a column from the users table. I'm not sure if this is what you want, but you should try:
SELECT COUNT(u.uid) AS answer , so.option_label
FROM survey_answer sa
RIGHT JOIN survey_question_options so
ON sa.option_id = so.option_id AND
sa.record_date>='2011-09-01' AND
sa.record_date<='2012-08-01'
LEFT JOIN users u
ON (sa.uid = u.uid AND u.gender='M')
WHERE so.question_id=24
GROUP BY so.option_label
ORDER BY so.option_id ASC
The left join to the users table is evaluated after the join to the answer table - so although the user record is not returned if the user is the wrong gender, the answer record will be returned (regardless of the user's gender). Try:
SELECT COUNT(sa.option_id) AS answer , so.option_label
FROM (select a.option_id
from survey_answer a
JOIN users u ON a.uid = u.uid AND u.gender='F'
where a.record_date>='2011-09-01' AND
a.record_date<='2012-08-01') sa
RIGHT JOIN survey_question_options so
ON sa.option_id = so.option_id
WHERE so.question_id=24
GROUP BY so.option_label
ORDER BY so.option_id ASC
You're putting your condition in the wrong block. Since you're performing a LEFT JOIN, (which is a left-bound outer join) everything in the left table (the main table) is selected, together with the data from the joined table, where applicable. What you want is to add the data from all users and then restrict the full output of the query. What you've actually done is add the user data from only the female users and then displayed all data.
Sounds technical, but all you have to do is move the AND u.gender='F' into the main WHERE clause instead the ON clause. That will cause SQL to only select the rows for female users after the JOIN has taken place.

Mysql - Join matches and non-matches

This is related to my other question:
Managing Foreign Keys
I am trying to join the table of matches and non-matches.
So I have a list of interests, a list of users, and a list of user interests.
I want the query to return all interests, whether the user has the interest or not (should be null in that case), only where the user = x. Every time I get the query working its only matching interests that the user specifically has, instead of all interests whether they have it or not.
You should rather use LEFT JOINS
Something like
SELECT *
FROM interests i LEFT JOIN
userinterests ui ON i.interestID = ui.interestID LEFT JOIN
users u ON ui.userID = u.uiserID
WHERE userID = ?
where is the user id you are looking for.
SELECT *
FROM interests i
LEFT JOIN userinterests ui ON i.interestID = ui.interestID
LEFT JOIN users u ON ui.userID = u.uiserID
and u.userID = ?
If you put a where condition on a table that should have no records inteh main tbale, you convert the join from a left join to an inner join. The only time you should ever have a condition inthe where clasue for something one the right side of a left join is when you are searching for records that don't match (where u.userid is null, for instance)
Of course you should define the fields to be selected and never use select * in production code especially not when you have a join as it sends repeated information across the network (the data inteh join feilds is repeated) and is a waste of resources and poor prgramming practice for multiple reasons.

Categories