I want to ask you about Friend Suggestions facebook like.
I have 2 table, that's : tb_user and tb_friend.
tb_user
uid | username | full_name
1 | dean | Dean Cool
2 | ryanblk | Ryan Black
3 | maria | Maria Bellen
4 | greg | Greg Munch
tb_friend
friend_one_id | friend_two_id | status
1 | 2 | 1
1 | 4 | 1
3 | 4 | 1
For status :
1 --> Friend
Now I want to query tb_user linking with tb_friend. Condition, if never friend (Status is not 1) then show it into suggestions friend.
My SQL query so far :
$uid --> my session
SELECT
U.uid, U.username, U.full_name FROM tb_user U
WHERE
U.uid != '$uid' ORDER BY RAND() LIMIT 3
Please help!
I had a similar scenario where i used this as query string
$query = "SELECT * FROM friend_table,user_table
WHERE ((from_id = '".$_SESSION['logged_user_id']."' AND friend_table.to_id = user_table.user_id)
OR
(to_id = '".$_SESSION['logged_user_id']."' AND friend_table.from_id = user_table.user_id))
AND
friend_table.status <> '1'";
I am editing my db_structure so that you understand
[WAIT TILL I GIVE DB STRUCTURE SO THAT YOU UNDERSTAND. I AM EDITING THE ANSWER]
My db struture was like this
user_table
|-------------------------------------------------------------|
| user_id | username | first_name | last_name |
|-------------------------------------------------------------|
| 1 | smruti | Smruti | Singh |
|-------------------------------------------------------------|
| 2 | sunaina | Sunaina | Singh |
|-------------------------------------------------------------|
my friend_table to store the realtion between friends
|-------------------------------------------------------------|
| relation_id | from_id | to_id | status |
|-------------------------------------------------------------|
| 1 | 1 | 2 | 1 |
|-------------------------------------------------------------|
| 2 | 3 | 4 | 0 |
|-------------------------------------------------------------|
EDIT
This wil show all the result of users who are not your friend.
Keep one thing in mind, if you sent a request to someone then a row is inserted into the friend_table with status 0. If he/she accepts, the status becomes 1. If he/she rejects, the staus becomes 2. If status is 2, you can again send request to him/her.
So here the user_id who are either present in friend_table with status not equal to 1, or who are not present at all.
$query = "SELECT * FROM user_table WHERE user_id NOT IN
(
SELECT user_id FROM friend_table,user_table
WHERE ((from_id = '".$_SESSION['logged_user_id']."' AND
friend_table.to_id = user_table.user_id)
OR
(to_id = '".$_SESSION['logged_user_id']."' AND
friend_table.from_id = user_table.user_id))
AND
friend_table.status = '1')";
Related
I have these tables...
GROUP_MEMBERS
+---------------------------------+
| id | group_id | member_id |
+---------------------------------+
| 1 | 1 | 1 |
| 2 | 1 | 4 |
+---------------------------------+
MEMBERS
+-------------------------------------+
| id | first | last | role_id |
+-------------------------------------+
| 1 | Jack | Jones | 1 |
| 2 | Jane | Doe | 2 |
| 3 | Bob | Bee | 2 |
| 4 | Jen | Nee | 1 |
+-------------------------------------+
GROUPS
+-----------------+
| id | name |
+-----------------+
| 1 | group1 |
| 2 | group2 |
+-----------------+
As it is, I am using the following query...
SELECT
(members.id) AS memid,
members.first,
members.last,
members.role_id
FROM
members
LEFT JOIN group_members ON
members.id = group_members.member_id
WHERE
group_members.member_id IS NULL
GROUP BY
members.id;
This outputs the members (Jane and Bob) who are not in the 'GROUP_MEMBERS' table as it should, but what I am trying get working is if I am on and another group ($_GET['group_id']), how can I show all members that do not have rows that match group_id and member_id on the 'GROUP_MEMBERS' table...
i.e if group_id = '2' show all members
I have tried adding in WHERE clause... AND group_members.group_id IS NULL.. but it shows nothing then.
Does anyone have a query which would get the output I'm looking for?
Thanks
[EDITED]
Just to clarify...
If my url had 'group_id=1'
I should see:
Bob
Jane
If my url has 'group_id=2'
I should see:
Jack
Jane
Bob
Jen
So it only shows 'members' that do not exist( with the 'group_id' in the url) in the 'GROUP_MEMBERS' table
If I have understood the question correctly, you are looking for something like I have made on this fiddle:
DB Fiddle
The query I use is:
$sql = 'SELECT * FROM groups
RIGHT JOIN group_members ON groups.id = group_id
RIGHT JOIN members ON member_id = members.id
WHERE group_id <> ? OR group_id is NULL;'
$group_id = $_GET['group_id'];
$query = $mysqli->prepare($sql);
$query->bind_param('i', $group_id);
In short, this query will select from the groups table, ensuring that we will select every group in your database.
Then we will join the other two tables completely (using the RIGHT JOIN).
Finally, we are going to select every member that isn't the specified the one provided by the URL, or any member that is not in a group.
You can use a sub-query
how can I show all members that do not have rows that match 'group_id'
$group_id= $_GET['group_id'];
$q = "SELECT * FROM MEMBERS WHERE MEMBERS.id NOT IN(
SELECT member_id FROM GROUP_MEMBERS WHERE group_id='$group_id'
);";
Explanation
SELECT member_id FROM GROUP_MEMBERS WHERE group_id='$grID'
this will get all the members in this group by a given ID
then you select all members that are not among them.
SELECT * FROM MEMBERS WHERE MEMBERS.id NOT IN()
this one will give members data except the ids inside the brackets
the sub query will get the ids of members in a given group
no need for joining the three tables since you are using id of the group existing in GROUP_MEMBERS and linking the GROUP and MEMBERS
one side note
if you have a group name and what all users not in this group you then will need to use the GROUPS table
SELECT * FROM MEMBERS WHERE MEMBERS.id NOT IN(
SELECT member_id FROM GROUP_MEMBERS WHERE group_id = (
SELECT id from GROUPS WHERE name = '$Group_Name'
)
);
you may use WHERE group_id IN (...) it will work the same
This is a demonstration, I created same database with same data and tested the queries
+----+-------+-------+---------+
| id | first | last | role_id |
+----+-------+-------+---------+
| 1 | Jack | Jones | 1 |
| 2 | Jane | Doe | 2 |
| 3 | Bob | Bee | 2 |
| 4 | Jen | Nee | 2 |
+----+-------+-------+---------+
+----+--------+
| id | name |
+----+--------+
| 1 | group1 |
| 2 | group2 |
+----+--------+
+----+----------+-----------+
| id | group_id | member_id |
+----+----------+-----------+
| 1 | 1 | 1 |
| 2 | 1 | 4 |
+----+----------+-----------+
I run the sub-query as above and the results as expected,
MariaDB []> select * from members where id not in
(select member_id from group_members where group_id = 1);
+----+-------+------+---------+
| id | first | last | role_id |
+----+-------+------+---------+
| 2 | Jane | Doe | 2 |
| 3 | Bob | Bee | 2 |
+----+-------+------+---------+
similar for when you have group name
MariaDB []> select * from members where id not in
(select member_id from group_members where group_id =
(select id from groups where name='group1'));
+----+-------+------+---------+
| id | first | last | role_id |
+----+-------+------+---------+
| 2 | Jane | Doe | 2 |
| 3 | Bob | Bee | 2 |
+----+-------+------+---------+
I need to develop chat application in php for this i have created two tables likes users and message. every user details will be stored in users table and every message will be stored in messages table.I have done storing part it is working fine. Now i need to display messages.So as per my requirement.
when any user logs into his portal he/she will be able to see latest messaged users list.And if he want to message any of other users ,he just clicks on there profile pic than a message panel will be opened .Untill here i completed everything.
But my issue is i need to display
latest messaged users list,
in this i need to show user first name, profile picture,last message, last message date.
And one more condition is i need to display the list like latest messaged user first.
I have tried in many ways but i got users list with first message i don't want like that i need last message for that user
My tables are
Users table
uid | firstname | email | mobile
---------------------------------------------
1 | kumar | kumar#gmail.com | 9876543210
----------------------------------------------
2 | jack | jack#gmail.com | 8876543216
----------------------------------------------
3 | rams | rams#gmail.com | 7876543215
----------------------------------------------
4 | devid | devid#gmail.com | 9876543220
----------------------------------------------
5 | joe | joe#gmail.com | 8876543212
----------------------------------------------
messages table
mid| from_id | to_id | message | created_at
----------------------------------------------------------------
1 | 1 | 2 | hello jack | 2017-02-03 09:00:52
----------------------------------------------------------------
2 | 2 | 1 | hi kumar | 2017-02-03 09:10:30
----------------------------------------------------------------
3 | 2 | 3 | ram where are you | 2017-02-03 09:15:02
----------------------------------------------------------------
4 | 3 | 2 | at home | 2017-02-03 09:35:20
----------------------------------------------------------------
5 | 1 | 2 | hello how are you | 2017-02-03 09:42:55
----------------------------------------------------------------
6 | 4 | 2 | good morning | 2017-02-03 09:50:45
----------------------------------------------------------------
8 | 1 | 3 | hi | 2017-02-03 09:54:22
----------------------------------------------------------------
7 | 3 | 1 | hello kumar | 2017-02-03 09:58:38
----------------------------------------------------------------
For example i have logged in as kumar(uid=1)
Expected output:
firstname | message | mid | uid
-----------------------------------------
rams | hello kumar | 7 | 3
-----------------------------------------
jack | hello how are you | 5 | 2
-----------------------------------------
I have tried like this :
SELECT DISTINCT
`u`.`firstname`,
`u`.`profile_photo`,
`u`.`uid`,
`u2`.`firstname`,
`u2`.`profile_photo`,
`u2`.`uid`,
`message`,
`messages`.`created_at`,
`messages`.`from_id`,
`messages`.`to_id`,
`messages`.`mid`
FROM
`messages`
INNER JOIN
`users` AS `u` ON `u`.`uid` = `messages`.`from_id`
INNER JOIN
`users` AS `u2` ON `u2`.`uid` = `messages`.`to_id`
WHERE
(from_id = 1 OR to_id = 1)
GROUP BY
`u`.`uid`,
`u2`.`uid`
ORDER BY
`messages`.`mid` DESC
But got output like this
firstname | message | mid | uid
-----------------------------------------
jack | hello jack | 1 | 2
-----------------------------------------
rams | hi | 5 | 2
-----------------------------------------
Thanks in advance
try this way
SELECT DISTINCT `u`.`firstname`,`u`.`profile_photo`, `u`.`uid`, `u2`.`firstname`,`u2`.`profile_photo`,`u2`.`uid`, `message`,`messages`.`created_at`, `messages`.`from_id`,`messages`.`to_id`,`messages`.`mid`
FROM `messages`
INNER JOIN `users` AS `u` ON `u`.`uid` = `messages`.`from_id`
INNER JOIN `users` AS `u2` ON `u2`.`uid` = `messages`.`to_id`
WHERE (from_id = 1 OR to_id = 1)
GROUP BY `u`.`uid`, `u2`.`uid`
ORDER BY `messages`.`created_at` DESC
It appears that you want to put messages in the same group if they're between the same two users, regardless of the direction. To do this, change your GROUP BY to:
GROUP BY GREATEST(u.uid, u2.uid), LEAST(u.uid, u2.uid)
Use this along with the solutions in SQL Select only rows with Max Value on a Column to get the first or last message in each conversation found using this grouping.
You should also give aliases to the columns from u and u2 in the SELECT clause, so you can distinguish the sender and receiver information in the result.
SELECT u.firstname AS sender_name, u.profile_photo AS sender_photo, ...
Or since one of the users is always kumar, you could just select only the information about the other user:
SELECT IF(from_id = 1, u2.firstname, u1.firstname) AS firstname,
IF(from_id = 1, u2.profile_photo, u1.profile_photo) AS profile_photo,
...
I have a left join query to get posts liked by a users. if 2nd logged in user visit the 1st user profile will show the likes by 1st user and also will show a text on the post if 2nd user (logged in user) like the same post
user table
user_id | username
likes table
like_id | post_id | uid
MySQL
$SQL = "SELECT * FROM likes LEFT JOIN users ON users.user_id = likes.uid WHERE likes.uid = 'user1'"
If i run another query inside the while loop of above query it will work
$check_id = row['post_id']; //get post id from 1st loop
if(isset($_SESSION['userid'])){
$check = "SELECT * FROM likes WHERE post_id='$check_id' AND uid='LOGED-IN-USER-ID'"
}
Then i can get the num_rows and add text. This work perfectly fine but i like to know is there a better way to do this without running so many queries inside the while loop. Is there a way to combine the queries or do the 2nd query outside of the loop.
That's "safe" from "data consistency point of view", but querying in a while after a query is called a "1+N" and is typically a performance killer, you may easily find documentation about SQL 1+N problem.
The solution is to let the SQL server do the job for you in a single query, avoiding playing ping pong with it (read: TCP packets back-and-forth, query parsing, ...).
Given:
> SELECT * FROM user;
+---------+----------+
| user_id | username |
+---------+----------+
| 1 | root |
| 2 | user2 |
| 3 | user3 |
+---------+----------+
> SELECT * FROM `like`;
+---------+---------+---------+
| like_id | post_id | user_id |
+---------+---------+---------+
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 3 | 1 |
| 4 | 4 | 1 |
| 5 | 2 | 2 |
+---------+---------+---------+
> SELECT * FROM `post`;
+---------+--------+
| post_id | text |
+---------+--------+
| 1 | post 1 |
| 2 | post 2 |
| 3 | post 3 |
| 4 | post 4 |
+---------+--------+
There's multiple way to request what you want, but one way may be:
> SELECT like_id, like.post_id, text,
(SELECT 1 FROM `like`
WHERE post_id = post.post_id AND
user_id = 2 /* logged in user */) AS I_like_it_too
FROM `like`
JOIN post USING (post_id)
WHERE user_id = 1 /* user id of seen profile */;
+---------+---------+--------+---------------+
| like_id | post_id | text | I_like_it_too |
+---------+---------+--------+---------------+
| 1 | 1 | post 1 | NULL |
| 2 | 2 | post 2 | 1 |
| 3 | 3 | post 3 | NULL |
| 4 | 4 | post 4 | NULL |
+---------+---------+--------+---------------+
The use the I_like_it_too alias to display post differently as needed.
From a performance point of view you'll need an index on like.user_id to restrict the selected rows on a little subset, the dependent subquery will only be ran for this subset, so that's OK.
Another possibility may be:
> SELECT displayed.like_id, displayed.post_id, text, my_likes.like_id is not null AS i_also_like
FROM `like` AS displayed
JOIN post USING (post_id)
LEFT JOIN `like` AS my_likes ON
displayed.post_id = my_likes.post_id AND
my_likes.user_id = 2 /* logged user */
WHERE displayed.user_id = 1 /* user id of seen profile */;
+---------+---------+--------+-------------+
| like_id | post_id | text | i_also_like |
+---------+---------+--------+-------------+
| 1 | 1 | post 1 | 0 |
| 2 | 2 | post 2 | 1 |
| 3 | 3 | post 3 | 0 |
| 4 | 4 | post 4 | 0 |
+---------+---------+--------+-------------+
Do u mean like this ?
Table SO_LIKES ( ur "Like" Table )
like_id | post_id | uid
1 | 1 | 1
2 | 2 | 1
3 | 1 | 2
Table SO_USERS ( ur "Users" Table )
user_id | username
1 | User1
2 | User2
SQL
SELECT * FROM SO_LIKES as t1 LEFT JOIN SO_USERS as t2 ON t1.uid = t2.user_id INNER JOIN SO_LIKES as t3 ON t1.post_id = t3.post_id WHERE t2.user_id = 1 AND t3.uid = 2
SO Simply call the Same Table in ur query again and use the ID of user 2 there
WHERE t2.user_id = 1 AND t3.uid = 2
Output Looks then like this
like_id | post_id | uid | user_id | username | like_id | post_id | uid
1 | 1 | 1 | 1 | User1 | 3 | 1 | 2
SO u get the POST_id 1 That both Users has Liked
I'm trying to create a system like twitter where user can connect to each other & then they will be able to see each other post
here is the user table
+-----+------------+---------+
| id | name |username |
+-----+------------+---------+
| 1 | Phillip | user1 |
| 2 | Another | user2 |
+-----+------------+---------+
connection table
+---------+-----------+--------------+--------------+
| id | follower | following | status |
+---------+-----------+--------------+--------------+
| 1 | user1 | user2 | 0 |
| 2 | user3 | user1 | 1 |
+---------+-----------+--------------+--------------+
post table
+---------+-----------+--------------+--------------+
| post_id | content | title | username |
+---------+-----------+--------------+--------------+
| 1 | hello guyz| eg1 | user1 |
| 2 | example1 | eg 2 | user2 |
+---------+-----------+--------------+--------------+
query i tried
SELECT
post.*
FROM users
LEFT JOIN connection ON (users.username = connection.follower
OR users.username = connection.following)
INNER JOIN messages ON (
users.username = post.username
OR connection.following = post.username
)
WHERE users.username = 'user1'
GROUP BY post.id
LIMIT 0, 8
What could be wrong in this query as this query is also incomplete
To make you understand better->
Suppose my name is example & if i send request to example2 & he accept my request then status will be set to 1 then how can i see his posts on my timeline & how can he see my posts on his timeline
The query for the results you want is
SELECT * FROM `posts`
WHERE `username` = 'user1'
OR `username` IN (SELECT `follower` FROM `connection` WHERE `following`='user1' AND `status`=1)
unfortunately i have to do this in mysql / php . I looked for three days, and there is like 10.000 explantions of this but NONE (and I repeat NONE) works for me. I tried it all. I have to ask, sorry.
I have two tables - articles and control.
table "articles"
------------------
art_id | name |
------------------
1 | aaa |
2 | bbb |
3 | ccc |
4 | ddd |
table "control"
--------------------------------------------
con_id | art_id | data |
--------------------------------------------
1 | 1 | something-a |
2 | 2 | something-b |
3 | 1 | something-a |
4 | 2 | something-c |
5 | 3 | something-f |
art_id exists in both tables. Now what i wanted - for query:
"select * from articles order by art_id ASC" displayed in a table
to have also one cell displaying the count for each of art_id's from table CONTROL...
and so i tried join, left join, inner join - i get errors ... I also tried for each get only one result (for example 2 for everything)... this is semi-right but it displays the array of correct results and it's not even with join!!! :
$query = "SELECT art_id, count(*) as counting
FROM control GROUP BY art_id ORDER BY con_id ASC";
$result = mysql_query($query);
while($row=mysql_fetch_array($result)) {
echo $row['counting'];
}
this displays 221 -
-------------------------------------------------
art_id | name | count (this one from control) |
-------------------------------------------------
1 | aaa | 221 |
2 | bbb | 221 |
3 | ccc | 221 |
and it should be:
for art_id(value1)=2,
for art_id(2)=2,
for art_id(3)=1
it should be simple - like a count of values from CONTROL table displayed in query regarding the "articles" table...
The result query on page for table articles should be:
"select * from articles order by art_id ASC"
-------------------------------------------------
art_id | name | count (this one from control) |
-------------------------------------------------
1 | aaa | 2 |
2 | bbb | 2 |
3 | ccc | 1 |
So maybe i should go with JOIN or with join plus for each... Tried tha too, but then i'm not sure what is the proper thing to echo... all-in-all i'm completely lost here. Please help. Thank you.
So imagine this in two steps:
Get the counts per art_id from the control table
Using your articles table, pick up the counts from step 1
That will give you a query that looks like this:
SELECT a.art_id, a.name, b.control_count
FROM articles a
INNER JOIN
(
SELECT art_id, COUNT(*) AS control_count
FROM control
GROUP BY art_id
) b
ON a.art_id = b.art_id;
Which will give you the results you're looking for.
However, instead of using a subquery, you can do it all in one shot:
SELECT a.art_id, a.name, COUNT(b.art_id) AS control_count
FROM articles a
INNER JOIN control b
ON a.art_id = b.art_id
GROUP BY a.art_id, a.name;
SQL Fiddle demo
SELECT *, (SELECT COUNT(control.con_id) FROM control WHERE control.art_id = articles.art_id) AS count_from_con FROM articles ORDER BY art_id DESC;
If I understood your question right, this query should do the trick.
Edit: Created the tables you have described, and it works.
SELECT * FROM articles;
+--------+------+
| art_id | name |
+--------+------+
| 1 | aaa |
| 2 | bbb |
| 3 | ccc |
| 4 | ddd |
+--------+------+
4 rows in set (0.00 sec)
SELECT * FROM control;
+--------+--------+------+
| con_id | art_id | data |
+--------+--------+------+
| 1 | 1 | NULL |
| 2 | 2 | NULL |
| 3 | 1 | NULL |
| 4 | 2 | NULL |
| 5 | 3 | NULL |
+--------+--------+------+
5 rows in set (0.00 sec)
SELECT *, (SELECT COUNT(control.con_id) FROM control WHERE control.art_id = articles.art_id) AS count_from_con FROM articles ORDER BY art_id ASC;
+--------+------+----------------+
| art_id | name | count_from_con |
+--------+------+----------------+
| 1 | aaa | 2 |
| 2 | bbb | 2 |
| 3 | ccc | 1 |
| 4 | ddd | 0 |
+--------+------+----------------+
You haven't quite explained what you want to accomplish with the print out but here is an example in PHP: (Use PDO instead of mysql_)
$pdo = new PDO(); // Make your connection here
$stm = $pdo->query('SELECT *, (SELECT COUNT(control.con_id) FROM control WHERE control.art_id = articles.art_id) AS count_from_con FROM articles ORDER BY art_id ASC');
while( $row = $stm->fetch(PDO::FETCH_ASSOC) )
{
echo "Article with id: ".$row['art_id']. " has " .$row['count_from_con'].' connected rows in control.';
}
Alternatively with the mysql_ extension:
$result = mysql_query('SELECT *, (SELECT COUNT(control.con_id) FROM control WHERE control.art_id = articles.art_id) AS count_from_con FROM articles ORDER BY art_id ASC');
while( $row = mysql_fetch_assoc($result) )
{
echo "Article with id: ".$row['art_id']. " has " .$row['count_from_con'].' connected rows in control.';
}
This should be enough examples to help you accomplish what you need.