Query to get reposts from people the user is following - mysql

I have a table posts where all the posts by users are stored, the structure of this table is as follows
| post_id | post_user | post_content | post_date |
the users table is as follows
| user_id | username | user_joined |
user relationship table is as follows
| follower | following | rel_date |
this is the query I am using to get the posts from people that user is following to show them.
SELECT * FROM posts WHERE post_user in(SELECT follower from user_follow where following=$loggedin_user)
Now I want users to share posts, for which I created a table repost_user as follows
| repost_user | original_post_user | post_id | repost_date |
I want to get posts from people that user following, which includes reposts too.. How do I do this?
EDIT : How my resultset should look
post_id | post_content | post_user | post_date | is_repost | repost_user | repost_date
for eg if its normal post the row should look like
23 | <some content> | 3 | <post date> | false | null | null |
if its a repost the rows would be
23 | <some content> | 3 | <post date> | true | 2 | <repost_date> |

Is that what You want ?
SELECT post_id,
post_content,
post_user,
post_date,
if(repost_user.post_id is null, 0,1) is_repost,
repost_user,
repost_date
FROM posts
LEFT join repost_user
on posts.post_id=repost_user.post_id
WHERE (repost_user in
(SELECT follower from user_follow where following=$loggedin_user)
or post_user in
(SELECT follower from user_follow where following=$loggedin_user) )
AND posts.post_id IS NOT NULL

Related

Selecting multiple table values with doubled joins

I have a query which selects values from different tables via JOIN. But I think I have a problem now, because one table needs to join in again with a different name, but somehow it doesn't work.
An example based on a social network strucutre:
Table "users":
+--------+-----------+
| userid | username |
+--------------------|
| 1 | userOne |
| 2 | userTwo |
| 3 | userThree |
+--------+-----------+
Table "posts":
+--------+---------+-------------------------------+
| postid | userid | text |
+--------------------------------------------------|
| 102 | 1 | "Haha i'm User one" |
| 103 | 1 | "And User one is the best" |
| 104 | 3 | "I'm having fun with user two"|
+--------+---------+-------------------------------+
Table "usertags":
+--------+---------------+
| postid | tagged_userid |
+------------------------|
| 104 | 2 |
+--------+---------------+
This is my query:
SELECT posts.postid,
posts.userid,
posts.text,
users.username,
IFNULL(GROUP_CONCAT(DISTINCT usertags.tagged_userid SEPARATOR ','), NULL) as
taggedusers_id,
IFNULL(GROUP_CONCAT(DISTINCT taggedusers.fullname SEPARATOR ','), NULL) as
taggedusers_name,
FROM posts
JOIN users ON posts.userid = users.userid
LEFT JOIN usertags ON posts.postid = usertags.postid
LEFT JOIN users as taggedusers ON usertags.tagged_userid = users.userid
GROUP BY posts.postid
ORDER BY posts.postid DESC
And that's the result i get:
+--------+---------+---------------------------------------------------------------------+
| postid | userid | text | username | taggedusers_id |
+-----------------------------------------------------------------------|----------------|
| 102 | 1 | "Haha i'm User one" | userOne | NULL |
| 103 | 1 | "And User one is the best" | userOne | NULL |
| 104 | 3 | "I'm having fun with user two"| userThree | 2
+--------+---------+-------------------------------+--------------------+----------------+
The problem:
The column 'taggedusers_name' shows up, but it always shows NULL. I want it to show the usernames of the users which are tagged.
Like this, but in the whole, big output
+---------------+-------------------+
| taggeduser_id | taggeduser_name |
+-----------------------------------|
| 2 | userTwo |
| 2,3 | userTwo,userThree |
| NULL | NULL |
+---------------+-------------------+
So, how is this possible? Do I need to make a multiple SELECT statement? I tried that already, but I failed at this too :/
I'd be glad for help!
The issue is that you're referencing users again without the alias. Since users is already being implicitly INNER JOIN (see this question What is the default MySQL JOIN behaviour, INNER or OUTER?) so the taggedusers table will have to meet the conditions that the author is the same as the tagged user ID.
SELECT posts.postid,
posts.userid,
posts.text,
users.username,
IFNULL(GROUP_CONCAT(DISTINCT usertags.tagged_userid SEPARATOR ','), NULL) as
taggedusers_id,
IFNULL(GROUP_CONCAT(DISTINCT taggedusers.fullname SEPARATOR ','), NULL) as
taggedusers_name,
FROM
posts
JOIN
users
ON posts.userid = users.userid
LEFT JOIN
usertags
ON posts.postid = usertags.postid
LEFT JOIN
users as taggedusers
ON usertags.tagged_userid = taggedusers.userid -- this is (I assume) what you meant
-- ON usertags.tagged_userid = users.userid -- this is your problem
GROUP BY
posts.postid
ORDER BY
posts.postid DESC
One way to avoid this is to always alias tables; in this case you could have aliased users as 'author' or something of the like.
The reason you didn't have the same problem with the distinct IDs is that it was on a table that was joined correctly.

MySQL - Left Outer Join not updating original table

I created a toy dataset where I am trying to count the number of posts for each user. I seem to be getting the correct count values but the count column in the users table is not updated with the values.
I'm new to mysql and very confused! Can somebody tell me what I'm doing wrong?
users:
+---------+------+-------+
| user_id | user | pword |
+---------+------+-------+
| 1 | Amy | abcd |
| 2 | Jess | efgh |
| 3 | Lori | ijkl |
+---------+------+-------+
posts:
+---------+-------------+------+
| post_id | post | user |
+---------+-------------+------+
| 1 | hi | Lori |
| 2 | hello | Jess |
| 3 | hello again | Jess |
| 4 | and again | Jess |
+---------+-------------+------+
mysql> ALTER TABLE users ADD COLUMN post_count INT;
mysql> SELECT u.user_id, COUNT(p.user) AS post_count FROM users u LEFT JOIN posts p ON u.user LIKE p.user GROUP BY u.user_id;
+---------+------------+
| user_id | post_count |
+---------+------------+
| 1 | 0 |
| 2 | 3 |
| 3 | 1 |
+---------+------------+
mysql> SELECT * FROM users;
+---------+------+-------+------------+
| user_id | user | pword | post_count |
+---------+------+-------+------------+
| 1 | Amy | abcd | NULL |
| 2 | Jess | efgh | NULL |
| 3 | Lori | ijkl | NULL |
+---------+------+-------+------------+
Thanks!!
Please try the following...
UPDATE users
JOIN ( SELECT u.user_id AS user_id,
COUNT( p.user ) AS post_count
FROM users u
LEFT JOIN posts p ON u.user LIKE p.user
GROUP BY u.user_id ) postCountFinder
ON users.user_id = postCountFinder.user_id
SET users.post_count = postCountFinder.post_count;
This question takes your list of users and post counts obtained from the following...
SELECT u.user_id,
COUNT( p.user ) AS post_count
FROM users u
LEFT JOIN posts p ON u.user LIKE p.user
GROUP BY u.user_id;
... and performs an INNER JOIN with Users on shared value of user_id, creating a dataset with every row from users having the corresponding count tacked on the end.
We then use the SET command to set the empty post_count from users to its corresponding joined count.
If you have any questions or comments, thenplease feel free to post a Comment accordingly.
You need update statement to update the value in the newly added column.Try this:
Update usr
set usr.post_count=tbl.post_count
from users usr
inner join
(select u.user_id,COUNT(p.user)
AS post_count FROM users u
LEFT JOIN posts p ON u.user LIKE p.user GROUP BY u.user_id ) tbl
on tbl.user_id=usr.user_id

Select column if results/row not exists?

I'm trying to select a list of post_ids from one column based on whether or not a user_id exists in another.
The idea is simply to get a list of post_ids that a user has not yet interacted with.
The table is like this with it's contents contents:
+----+---------+---------+--------+---------------------+------------+------+
| id | post_id | user_id | rating | last_update | num_images | url |
+----+---------+---------+--------+---------------------+------------+------+
| 1 | 2938 | 5 | 1 | 2014-06-12 22:54:31 | NULL | null |
| 2 | 2938 | 1 | 1 | 2014-06-12 22:54:54 | NULL | null |
| 3 | 2940 | 6 | 1 | 2014-06-12 23:36:25 | NULL | null |
| 4 | 2943 | 3 | 0 | 2014-06-12 23:39:29 | NULL | NULL |
+----+---------+---------+--------+---------------------+------------+------+
My attempt was this:
SELECT Distinct post_id
FROM `table`
WHERE user_id !=1
Yet I am still getting results that still gives results where the user has already been connected with the post -- it just excludes the entry including the user.
How do I get results on the condition that the user_id has not been connected with any instance of post_id in the compared column?
Your query should be :
select distinct(post_id )
from tableName
where post_id not in(select post_id from tableName where user_id=1);
My proposal
SELECT Distinct post_id
FROM `table` T
WHERE post_id NOT IN (
/*select posts NOT to be shown */
SELECT post_id
FROM `table` T1
/* naming the tables differently allows you to make operations
with data of the inner selection -T1- AND the outer one -T-
*/
WHERE T1.user_id = 1
)
First you need to find out list of post_id for the given user_id and then omit those post ids.
Try this:
select distinct post_id
from table
where post_id not in (select post_id from table where user_id=1);

Multiple tables join in SQL for this scenario

This is my table structure
I have 3 tables:
member table
comments table
comments like table
The tables structures can be found in the following images:
Table: member
--------------------------------------------------------------------
user_id |full_name |email | password | image |join_date |
| | | | | |
---------------------------------------------------------------------
Table: album_comments
--------------------------------------------------------------------
id |album_id |comment_text | comment_userid | post_date |active_bit |
| | | | | |
---------------------------------------------------------------------
Table: comment_likes
--------------------------------------------------------------------
id |user_id |comment_id | post_date | | like_bit |
| | | | | |
---------------------------------------------------------------------
I want to join three tables and retrieve the result. Here is what I need:
I want to return latest 20 comments and check if the member who is currently logged in has liked any of the comment in these 20 comments. If yes then return status bit as 1 for those comments and if not then return status bit 0.
Can anyone tell what would be the SQL query for this?
The following query should work for you. Select required columns from album_comments join it with comment_likes based on comment_id and check if the comment_likes user_id is equal to the user_id you sent from UI. ORDER BY DESC will return latest comments with LIMIT of 20.
Select |ac.Column1, ac.Column2...ac.Column-n|, cl.like_bit
FROM album_comments ac INNER JOIN comment_likes cl
ON ac.id = cl.comment_id AND cl.user_id = |screen user_id|
ORDER BY ac.id DESC LIMIT 20;

SQL join 2 tables together

I have a problem with joining 2 tables
Here is my first table with the name "users"
user_id user_username user_password user_name
1 admin admin123 john
3 test test123 alex
And here is my second table "posts"
post_id post_content post_userid
1 Lorem ipsum.. 1
2 Second post .. 3
I wanna show it like this:
post_id | post_content | post_userid | user_id | user_username | user_password | user_name
--------|----------------|-------------|---------|---------------|---------------|---------------
1 | Lorem ipsum.. | 1 | 1 | admin | admin123 | john
2 | Second post .. | 3 | 3 | test | test123 | alex
I've allready tried
SELECT * FROM posts INNER JOIN users ON(post_userid = user_id)
but that only shows the first post.
Then i tried
SELECT * FROM posts FULL OUTER JOIN users ON(post_userid = user_id)
that came out like this
post_id | post_content | post_userid | user_id | user_username | user_password | user_name
--------|----------------|-------------|---------|---------------|---------------|----------
1 | Lorem ipsum.. | 1 | 1 | admin | admin123 | john
2 | Second post .. | 3 | NULL | NULL | NULL | NULL
NULL | NULL | NULL | 3 | test | test123 | alex
SELECT * FROM posts AS p LEFT JOIN users AS u ON u.user_id = p.post_userid
SELECT
post_id,
post_content,
post_userid,
user_id,
user_username,
user_password,
user_name
FROM posts
INNER JOIN users ON user_id = post_userid
since i think your select should work, i suspect character fields for your ids. thus i suggest you try this join:
SELECT *
FROM posts
INNER JOIN
users
ON (rtrim(ltrim(post_userid)) = ltrim(rtrim(user_id)));
if that works, you should clean up your ids like this:
update posts
set post_userid = ltrim(rtrim(post_userid));
update users
set user_id = ltrim(rtrim(user_id));
also you should check whether your application inserts those blanks/whitespaces into your tables and stop it doing so.
Select * From posts p
INNER JOIN users u
ON u.user_id = p.post_userid