PHP - Not able to link tables to get the required information - php

Scenario
A user can show an interest to attend an event's dinner and the people who administer that event can choose to accept their request or not and if the request has already been accepted the "Accept" button should then be disabled.
Whats working
Everything is working till the part where the button needs to be disabled, the information is displaying right and i am having hard time linking database tables up so i can then use the information i need to disable the button.
The Attempt
This is what my query looks like
SELECT
r.id as request_id,
r.status as dinner_status,
r.dinner_id,
d.name as dinner_name,
d.date as dinner_date,
u.first_name as user_first_name,
u.last_name as user_last_name,
u.id as user_id,
u.description as user_description,
u.profile_image as user_profile_image,
c.name as user_college_name,
c.id as user_college_id,
c.slug as user_college_slug
FROM `requests` r
LEFT JOIN `college_dinners` d ON r.dinner_id = d.id
LEFT JOIN `user` u ON r.guest_id = u.id
LEFT JOIN `college` c on u.college_id = c.id
WHERE d.college_id = $collegeId
AND u.id = '77'
Now the most important part.
There is a table called invitations that keeps the guest_id and dinner_id ONLY if their request for dinner has been excepted. How can i make use of this invitations table to update my query and include information in it based on which i can enable and disable button on my view?
The PHP Attempt
I am open to solving this in PHP it self too, so I decided the use the foreach loop for the results that i get from above query and inside the foreach i am creating another query to the table invitations and then using if i am checking if the current loop's dinner_id matches the dinner_id and the same for guest_id of the second query inside the foreach but by doing that i the index gets screwed.
foreach ($invitations as $invitation) {
$invitatedSQL=".....";
if ( $invitedResult['guest_id'] == $invitation['user_id'] && $invitedResult['dinner_id'] == $invitation['dinner_id'] ) {
$isInvited = 'yes';
}
}
Please note that I do not need any help on the front end, its just the mysql query that I am having the problem with. I will really appreciate any help on this matter

Just a simple, left join. If the condition is false, there will be NULLs.
LEFT JOIN `invitations` i on r.guest_id = i.guest_id AND r.dinner_id = i.dinner_id
P.S.
Few of Your LEFT JOINs acts like a plain INNER JOINs. You should read about differences.
What is the difference between "INNER JOIN" and "OUTER JOIN"?

Related

SQL Inner Join query doesn't return all records, but instead the first one ever made

SELECT user.name, comments.cdata, comments.likes FROM comments
WHERE pid = $postNum
INNER JOIN user ON comments.uid = user.uid
ORDER BY cdate
Quick Notes:
I am a beginner, please don't be rude to me, I am trying to learn more
Yes, I have tried LEFT JOIN, but that just returns an SQL sintax error
My database is like this:
2 tables, 1 one is comments, comments has comments.cdata, comments.likes and comments.uid, the user one has the name of the user.
What I have been trying to accomplish is getting the name of the user with the comment data, instead of UID and comment data.
I also can not use 2 queries, due to me getting all the records and then displaying them on page via PHP for each.
Your query is syntactically incorrect. JOIN is an operator in the FROM clause. WHERE is a clause that follows the FROM clause.
In addition, I think the cdata and cdate should be the same thing, although I don't know what.
I also recommend using table aliases. So:
SELECT u.name, c.cdata, c.likes
FROM comments c JOIN
user u
ON c.uid = u.uid
WHERE c.pid = $postNum
ORDER BY c.cdata

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;

mysql/php: show posts and for each post all comments

I know this question has been asked multiple times (however, I could still not find a solution):
PHP MYSQL showing posts with comments
mysql query - blog posts and comments with limit
mysql structure for posts and comments
...
Basic question: having tables posts, comments, user... can you with one single select statement select and show all posts and all comments (with comment.user, comment.text, comment.timestamp)? How would such a select statement look like? If not, what is the easiest solution?
I also tried to JOIN the comments table with the posts table and use GROUP BY, but I got either only one comment in each row or each comment but also those posts multiple times!?
I tried the solution of the first link (nested mysql_query and then fetch) as well as the second link (with arrays). However, the first caused a bunch of errors (the syntax in that post seems to be not correct and I could not figure out how to solve it) and in the second I had problems with the arrays.
My query looks like this till now:
SELECT p.id, p.title, p.text, u.username, c.country_name, (SELECT SUM(vote_type) FROM votes v WHERE v.post_id = p.id) AS sum_vote_type FROM posts p LEFT JOIN user u ON ( p.user_id = u.id ) LEFT JOIN countries c ON ( c.country_id = u.country_id ) ORDER BY $orderby DESC
I was wondering if this issue was not very common, having posts and comments to show...?
Thank you for every help in advance!
Not knowing your database structure, it should look something like this. Note that you should replace the * characters with more explicit lists of columns you actually need.
SELECT p.*, c.*, u.* FROM posts p
LEFT JOIN comments c ON c.post_id = p.id
LEFT JOIN users u ON u.id = p.author_id
Note that if you're just trying to get counts, sums and things like that it's a good idea to cache some of that information. For instance, you may want to cache the comment count in the post table instead of counting them every query. Only count and update the comment count when adding/removing a comment.
EDIT:
Realized that you also wanted to attach user data to each comment. You can JOIN the same table more than once but it gets ugly. This could turn into a really expensive query. I also am including an example of how to alias columns so it's less confusing:
SELECT p.*, c.*, u.name as post_author, u2.name as comment_author FROM posts p
LEFT JOIN comments c ON c.post_id = p.id
LEFT JOIN users u ON u.id = p.author_id
LEFT JOIN users u2 ON u2.id = c.author_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