SQL query using LIKE and Union - php

I'm trying to generate a list of friends for users to invite to an event, however only if they're not already attending the event or have a pending invite request.
The way my friends system works, there are 3 columns in the table. userid1, userid2, and friendstatus. The user who sent the request goes into column 1(userid1), the user who received the request goes into column 2(userid2). Since the user creating the event could be in either column, I use the following query when adding friends to the event.
//this block is finding friends from column1
SELECT userid1 as friendID
FROM friends
WHERE userid2 = $myUsername AND friendstatus = 1
UNION
// this section is finding friends from column 2
SELECT userid2 as friendId
FROM friends
WHERE userid1 = $myUsername AND friendstatus = 1
I set the userid as friendID because this query generates a list which I then use checkboxes for (which the value is determined from)
However, once the event is created if users attending it want to add more friends, I need a way to pull their friends but only if those friends are not alread attending or have a pending request.
The column in my events table for users attending is called acceptedInvites and the column for pending requests is in inviteRequest.
So, here's the query that I can't get to work. If the userid is in the acceptedInvites or inviteRequest DO NOT select that value
//this section is finding friends from column1
SELECT
events.inviteRequest,
events.acceptedInvites,
friends.userid1 as friendID
FROM friends
LEFT JOIN events on
friends.userid1 NOT LIKE '%events.inviteRequest%' AND
friends.userid1 NOT LIKE '%events.acceptedInvites%'
WHERE friends.userid2 = $userid AND friends.friendstatus = 1
UNION
//this section is finding friends from column 2
SELECT users.userid2 as friendId
FROM friends
LEFT JOIN events on
friends.userid2 NOT LIKE '%events.inviteRequest%' AND
friends.userid2 NOT LIKE '%events.acceptedInvites%'
WHERE friends.userid1 = $userid AND friends.friendstatus = 1
For example:
friends table
columns are friend1, friend2 and friendstatus
(row 1) userid1:1 userid2:userid2 friendstatus:1
(row 2) userid1:3 userid2:1 friendstatus:1
-userid1 is friends with userid1 and userid3. As I stated above, the user in userid1
events table
columns used are acceptedInvites inviteRequests
(row 1) acceptedInvites: "1~2" inviteRequests : " "
-userid1 and userid2 are attending the event, no pending invites
Based on this, if userid1 wants to add more friends only userid3 will show up.

I think you meant the following:
events.inviteRequest NOT LIKE '%' + friends.userid1 + '%'
This would be better, but wouldn't be correct either. How are you separating userIds in your inviteRequest? Assuming they are comma-separated, the following condition returns false even though userid 3 is not in the list:
'23,35,35' NOT LIKE '%3%'
See my point? A trick to fix this is to add a comma to both sides of inviteRequest, then you'll have something like:
',23,35,35,' NOT LIKE '%,3,%' -- Note the commas around 3.
Hope it helps!

Related

What join to use

I have two tables, one for registered users and one to store votes.
We are logging in with registrants.id and registrants.zipcode. Once they vote their votes are inserted into the votes table, along with their Registration ID.
Im trying to right a select statement that returns a record that will select all the records for Matched ID and Zipcode, but the ID is not in the Votes.voter column. i have tried all kinds of variations of all the joins i can think of. is it something simple i am missing.
SELECT * FROM registrants
LEFT JOIN votes on registrants.id = votes.voter
WHERE registrants.id = 1 AND registrants.zipcode = 46706 and votes.voter <> 1
Perhaps a not exists query:
select * from registrants
where registrants.zipcode = '46706'
and not exists (select 1 from votes where registrants.id = votes.voter)

How can I compare 2 tables in mysql and check the result

I have two tables, one of them is for friends of a person and another one is for channel member.
I want to check if one of my friends is one of the channel members. If so don't show his name, else show him.
$get_friend = "select * from friends where user_1_id='$user_id' AND friends_status=1";
$run_friend = mysqli_query($conn,$get_friend);
$select_members = "SELECT user_id from channel_members where channel_id='$channel_id'";
$run_members = mysqli_query($conn,$select_members);
Try this query :
select * from friends where user_1_id='$user_id' AND friends_status=1 AND user_2_id NOT IN(SELECT user_id from channel_members where channel_id='$channel_id')
This will select all your friends from friends table which are not a member of channel '$channel_id'
SELECT
friends.*
FROM
friends
LEFT JOIN channel_members
ON channel_members.channel_id = '$channel_id'
AND channel_members.user_id = friends.user_2_id
WHERE
user_1_id = '$user_id'
AND friends_status = 1
AND channel_members.channel_id IS NULL
You can use this query.
I added an excluding LEFT JOIN.
It will try to join the members of the channel who are your friends to the result, but by specifying channel_members.channel_id IS NULL in the where clause you are filtering those datasets out which really have a member in the channel - leaving you with only the friends who are not in the channel.

Social timeline SQL logic

I am not experienced with MySQL genius so pardon me. I have 2 tables,
TABLE 1 contains column names: post_id (int, Auto Increment), post (varchar, user posts) and like (int) {like is incremented when a user likes the post e.g similar to facebook likes}
TABLE 2 contains column name: id (int, Auto Increment) and post_id(int, foreign key to TABLE 1), user_id(varchar, User who liked this post)
Now here is the tricky part for me, I want to select all posts from TABLE 1 and also indicate to the user which post has already been liked through TABLE 2 when a user requests for timeline, thus preventing the user from liking the the post again e.g how likes works on Instagram or any other social network i.e unlike if already liked.
What I tried using PHP and MySQL: Basically I retrieved all post from TABLE 1 based on the user retrieving a timeline and then I retrieved all data from TABLE 2 based on the user who needs the timeline, then I check to see if there is a match with TABLE 1's returned data and TABLE 2's returned data. With each returned post in the timeline I tag 1 to indicate in code the incoming post has been liked and 0 for not liked and then I display the appropriate UI flow to user in doing so I can make sure the user does not like the same post twice.
Selecting all from TABLE 2
SELECT * FROM `TABLE_2` WHERE `username` = :username
Selecting from TABLE 1
SELECT * FROM `TABLE_1` WHERE `reporter` IN (SELECT `destination_id` FROM `followers` WHERE `source_id` = :username)
UNION
SELECT * FROM `TABLE_1` WHERE `reporter` = :username
ORDER BY `created_at` DESC LIMIT 20
The above query returns a users timeline based on another logic and certain other factors
Now I compare both returned data from TABLE 1 and TABLE 2
if($likes != NULL)
{
$count = 0;
foreach($returnedtimeline["posts"] as $single)
{
if(array_search($likes[$count], $single) == "id")
{
$returnedtimeline["posts"][$count]["liked"] = 1;
$count++;
}else{
$returnedtimeline["posts"][$count]["liked"] = 0;
$count++;
}
}
But I believe there is a better way I can do this through one direct query than multiple queries because my methods has large disadvantages with time, amount of data and processing power of the server.
I believe you just want join in your select, to return columns from both tables at once. Something like:
select
post_id,
case when "Table 2".post_id is null then 0 else 1 end as UserHasLiked
from "Table 1"
left join "Table 2" on "Table 1".post_id = "Table 2".post_id
I'm not a MYSQL user, so the syntax may be a little off, but it should be pretty close I think.
SELECT DISTINCT *,
CASE WHEN likes.face_id = persona.face_id THEN '1' ELSE '0' END liked,
CASE WHEN dislikes.face_id = persona.face_id THEN '1' ELSE '0' END disliked,
CASE WHEN comments.face_id = persona.face_id THEN '1' ELSE '0' END commented
FROM persona, likes, dislikes, comments
RIGHT JOIN tagged ON tagged.phone_id = :pid WHERE persona.face_id = tagged.face_id
works like magic.

show results of multiple mysql tables and sort

I have 4 tables:
Table 1: Users
id
username
Table 2: Acts
act_id
act
user_id
act_score
act_date
Table 3: Votes
vote_id
act_id
user_voter_id
score_given
date_voted
Table 4: Comments
comment_id
comment
commenter_id
act_commented
date_commented
I want to show the contents of Acts Votes and Comments, based on User ID, combined in a list sorted in date order. Similar idea to Facebook's NewsFeed.
Sample output:
05-02-2014 10:00 Comment: "That's funny"
04-02-2014 12:30 Act Posted: "This is what I did"
04-02-2014 11:00 Comment: "Rubbish"
03-02-2014 21:00 Comment: "Looks green to me"
02-02-2014 09:00 Voted: +10 "Beat my personal best" by Cindy
01-02-2014 14:25 Act Posted: "Finally finished this darn website!"
I have tried to go down the create VIEW route to add all the required info to a table but
it was the wrong path. Now I'm not sure what to do!
Use UNION to combine separate queries. For example, to get the 10 most recent events across the three tables:
(
-- my acts
SELECT a.act_date timestamp,
'Act Posted' type,
a.act description,
u.username
FROM Acts a
JOIN Users u ON u.id = a.user_id
WHERE a.user_id = ?
ORDER BY a.act_date DESC
LIMIT 10
) UNION ALL (
-- votes on my acts
SELECT v.date_voted,
CONCAT('Voted ', v.score_given),
a.act,
u.username
FROM Votes v
JOIN Acts a USING (act_id)
JOIN Users u ON u.id = v.user_voter_id
WHERE a.user_id = ?
ORDER BY v.date_voted DESC
LIMIT 10
) UNION ALL (
-- comments on my acts
SELECT c.date_commented,
'Comment',
c.comment,
u.username
FROM Comments c
JOIN Acts a ON a.act_id = c.act_commented
JOIN Users u ON u.id = c.commenter_id
WHERE a.user_id = ?
ORDER BY c.date_commented DESC
LIMIT 10
)
ORDER BY timestamp DESC
LIMIT 10
first of all make id as a foreign key and use it in rest of the 3 tables while inserting data into those 3 tables.
like for Acts table,table structure should be like below.
Table 2: Acts
id //this is user id which is stored in the session while login.
act_id
act
user_id
act_score
act_date
The another thing to do is manage session for each and every user while he/she logged in.
Store user_id in the session for the further use like below.
session_start();
$_SESSION['user_id']=$_POST['ID'];
Then,fire select query for the particular table.I give you example of select query.
$sql="select * from Acts where id='".$_SESSION['id']."' ORDER BY act_date DESC";
$query=mysql_query($sql) or die("query failed");
Now, you will get result of Acts of particular user order by date.Then print it wherever you want.

MySQL - Complex query issue, multiple tables

I'm having a bit of trouble figuring out an SQL statement that I need to make.
I have 2 tables
Friends
===================================
friendfromid | friendtoid | request
===================================
Users
=================
userid | username
=================
I need to get the userid and username of each user that is my friend.
My id is either in the friendfromid or friendtoid depending on if I am requested the user or the user requested me.
So basically what needs to happen is the script needs to look at the friends table, get all the rows where my id is either friendfromid or friendtoid check that the request field is set to 1, take all the rows that fit that match then get the ids and usernames of each friendfromid or friendtoid which isn't mine.
For instance, if my id was 8 and the friends id was 9, let's say they requested me their id would be in the friendfromid field and my id would be in the friendtoid field, that means the script would take their id (9) and match it to that user in the users table.
This will give friends list with friend id and friend name:
SELECT u.userid , u.username
FROM Friends f
JOIN Users u
ON (( f.friendfromid ={the ID} AND friendtoid=u.userid)
OR ( f.friendtoid = {the ID} AND friendfromid=u.userid))
WHERE f.request = 1
Put {the ID}= user id whose friend list required.
Should be something like this:
SELECT *
FROM users
JOIN friends
ON friendfromid != userid
OR friendtoid != userid
WHERE request = 1
AND userid = {the ID}
Can't achieve in 1 query.
To get friendtoid with "my user ID" in friendfromid field:
SELECT b.friendtoid FROM Users a, Friends b WHERE request=1 AND friendfromid = a.userid
Vice versa for friendfromid.
Use a UNION query, joining to friends as below
SELECT username FROM user INNER JOIN friends ON (userid = friendfrom) WHERE friendto = {myid) AND request = 1
UNION
SELECT username FROM user INNER JOIN friends ON (userid = friendto) WHERE friendfrom = {myid} AND request = 1
Remember you need indexes on the friendto and friendfrom columns for performance

Categories