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);
Related
I have this query:
INSERT INTO Votes (id_post,id_user)
SELECT ?,?
FROM Posts p, Users u
WHERE p.id_user = :id_author
AND u.id = $_SESSION['id']
AND u.active = 1
limit 1;
Now I want to use JOIN instead of ,. But there isn't any common column between those two tables. So what should I write in ON clause?
What I'm trying to do:
I have three tables:
// Posts
+----+----------+---------------+-----------+
| id | title | content | id_author |
+----+----------+---------------+-----------+
| 1 | title1 | content1 | 1234 |
| 2 | title2 | content2 | 5678 |
+----+----------+---------------+-----------+
// ^ the id of post's author
// Users
+----+--------+--------+
| id | name | active |
+----+--------+--------+
| 1 | jack | 1 |
| 2 | peter | 0 |
| 3 | John | 1 |
+----+--------+--------+
// Votes
+----+---------+---------+
| id | id_post | id_user |
+----+---------+---------+
| 1 | 32 | 1234 |
| 2 | 634 | 5678 |
| 3 | 352 | 1234 |
+----+---------+---------+
// ^ the id of current user
Now I need to check two conditions before inserting a new vote into Votes table:
Is the id of author the same as what I pass as id_author? Posts.id_user = :id_author (I know I can do that by a FK, but I don't want)
The account of current user is active? Users.active = 1
Sum Up: I'm trying to don't let people be able to vote who are inactive (active = 0). For example if Stackoverflow bans you, then you cannot vote to posts anymore, because you (current user) are banned. So I'm pretty sure $_SESSION['id'] should be used in the query to determine current user.
I suggest using exists instead of join:
INSERT INTO Votes (id_post, id_user)
SELECT id_post, id_user FROM (SELECT ? id_post, ? id_user) a
WHERE EXISTS (
SELECT 1 FROM Users
WHERE id = ?
AND active = 1
) AND EXISTS (
SELECT 1 FROM posts
WHERE id_user = :id_author
)
You already have a join here! This is an implicit join.
INNER JOIN and , (comma) are semantically equivalent in the absence of
a join condition: both produce a Cartesian product between the
specified tables (that is, each and every row in the first table is
joined to each and every row in the second table).
So there isn't a need for you to 'introduce' a join here.
I have a table like this
| user_id | company_id | employee_id |
|---------|------------|-------------|
| 1 | 2 | 123 |
| 2 | 2 | 123 |
| 3 | 5 | 432 |
| 4 | 5 | 432 |
| 5 | 7 | 432 |
I have a query that looks like this
SELECT COUNT(*) AS Repeated, employee_id, GROUP_CONCAT(user_id) as user_ids, GROUP_CONCAT(username)
FROM user_company
INNER JOIN user ON user.id = user_company.user_id
WHERE employee_id IS NOT NULL
AND user_company.deleted_at IS NULL
GROUP BY employee_id, company_id
HAVING Repeated >1;
The results I am getting look like this
| Repeated | employee_id | user_ids |
|---------|--------------|------------|
| 2 | 123 | 2,3 |
| 2 | 432 | 7,8 |
I need results that look like this
| user_id |
|---------|
| 2 |
| 3 |
| 7 |
| 8 |
I realize my query is getting more, but that's just to make sure I'm getting the correct data. Now I need to get a single column result with each user_id in a new row for updating based on user_id in another query. I've tried this by only selecting the user_id but I only get two rows, I need all four rows of duplicates.
Any ideas on how to modify my query?
Here is the query to get all of your user_ids:
SELECT user_id
FROM user_company uc
INNER JOIN
(
SELECT employee_id, company_id
FROM user_company
WHERE employee_id IS NOT NULL
AND deleted_at IS NULL
GROUP BY employee_id, company_id
HAVING COUNT(employee_id) >1
) AS `emps`
ON emps.employee_id = uc.`employee_id`
AND emps.company_id = uc.`company_id`;
This query below will generate the query you are looking for.
SELECT CONCAT('UPDATE user_company SET employee_id = null WHERE user_id IN (', GROUP_CONCAT(user_id SEPARATOR ', '),')') AS user_sql
FROM user_company uc
INNER JOIN
(SELECT employee_id, company_id
FROM user_company
WHERE employee_id IS NOT NULL
AND deleted_at IS NULL
GROUP BY employee_id, company_id
HAVING COUNT(employee_id) >1) AS `emps`
ON emps.employee_id = uc.`employee_id`
AND emps.company_id = uc.`company_id`;
I have a table from Wordpress, wp_commentmeta, where I try to allow users to like comments. It looks like this
+---------+------------+-----------------------+---------------------+
| meta_id | comment_id | meta_key | meta_value |
+---------+------------+-----------------------+---------------------+
| 23 | 6 | like | 2 |
| 31 | 8 | like | 1 |
| 32 | 6 | like | 1 |
+---------+------------+-----------------------+---------------------+
I know how to get what comments are liked by user 2
SELECT * FROM `wp_commentmeta` WHERE meta_key="like" AND meta_value=2
But what I want to know is; Is it possible to build a select statement so that I get only comments NOT liked by user 2 so that the output looks like the following?
+---------+------------+----------+------------+
| meta_id | comment_id | meta_key | meta_value |
+---------+------------+----------+------------+
| 31 | 8 | like | - |
+---------+------------+----------+------------+
Yes. You can use aggregation and a having clause:
select comment_id
from wp_commentmeta
where meta_key = 'like'
group by comment_id
having sum(meta_value = 2) = 0;
The sum() in the having clause counts the number of likes where the user is 2. The = 0 says that there are none.
Note: This will only select comments that are liked but not liked by 2. If you also want comments that are never liked, then you need a list of comments somehow. Your question doesn't have enough information for this variation.
You can do that with aggregates, but most probably it will work slower. This is an example with NOT EXISTS
SELECT
*
FROM
wp_commentmeta c
WHERE
meta_key = "like"
AND NOT EXISTS ( SELECT
1
FROM
wp_commentmeta c1
WHERE
c1.metavalue = 2
AND c1.comment_id = c.comment_id
AND meta_key = "like" )
I have a table called real_estate its structure and data is as follows:-
| id | user_id | details | location | worth
| 1 | 1 | Null | Null | 10000000
| 2 | 1 | Null | Null | 20000000
| 3 | 2 | Null | Null | 10000000
My query is the folloeing:
SELECT * , SUM( worth ) as sum
FROM real_estate
WHERE user_id = '1'
The result which I get from this query is
| id | user_id | details | location | worth | sum
| 1 | 1 | Null | Null | 10000000 | 30000000
I want result to be like
| id | user_id | details | location | worth | sum
| 1 | 1 | Null | Null | 10000000 | 30000000
| 2 | 1 | Null | Null | 20000000 | 30000000
Is there any way to get the result the way I want or should I write 2 different queries?
1)To get the sum of worth
2)To get all the rows for that user
You need to use a subquery that calculates the sum for every user, and then JOIN the result of the subquery with your table:
SELECT real_estate.*, s.user_sum
FROM
real_estate INNER JOIN (SELECT user_id, SUM(worth) AS user_sum
FROM real_estate
GROUP BY user_id) s
ON real_estate.user_id = s.user_id
WHERE
user_id = '1'
but if you just need to return records for a single user, you could use this:
SELECT
real_estate.*,
(SELECT SUM(worth) FROM real_estate WHERE user_id='1') AS user_sum
FROM
real_estate
WHERE
user_id='1'
You can do your sum in a subquery like this
SELECT * , (select SUM(worth) from real_estate WHERE user_id = '1' ) as sum
FROM real_estate WHERE user_id = '1'
Group by id
SELECT * , SUM( worth ) as sum FROM real_estate WHERE user_id = '1' group by id
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