Select approved comments and unapproved comments of current user MySQL PHP - php

I'm new to mysql and I have a problem with selecting data from mysql database:
$post_id = 3;
$current_user_id = 1;
$query = "SELECT `comments`.*, `users`.`username`, `users`.`image` FROM (`comments`)
LEFT JOIN `users` ON `comments`.`user_id` = `users`.`id`
WHERE `comments`.`post_id` = '$post_id'
AND `comments`.`status` = 1
AND `users`.`status` = 1
ORDER BY `comments`.`date` desc";
This select, selects all approved comments from database, but also, in this select, I need all unapproved comments of $current_user_id,
Result must look like:
[all approved post comments] + [all unapproved post comments of $current_user_id]

not sure if this will really work, but just give a try and see. I can't test the query since we don't have the schema.
SELECT `comments`.*, `users`.`username`, `users`.`image` FROM (`comments`)
LEFT JOIN `users` ON `comments`.`user_id` = `users`.`id`
WHERE `comments`.`post_id` = '$post_id'
AND (
(`comments`.`status` = 1 AND `users`.`status` = 1)
OR
( `comments`.`status` = 0 AND `users`.`id`= '$current_user_id' )
)
ORDER BY `comments`.`date` desc
What I thought is select all the approved comments OR ( comments that are not approved, but from this user ). You might have to alter the query till you get what you really needed, I'm just giving you the idea, not the exact query. Hope this will help you.

SELECT `comments`.*, `users`.`username`, `users`.`image` FROM (`comments`)
LEFT JOIN `users` ON `comments`.`user_id` = `users`.`id`
WHERE `comments`.`post_id` = '$post_id'
AND `comments`.`status` = 1
AND `users`.`status` = 1
UNION ALL
SELECT `comments`.*, `users`.`username`, `users`.`image` FROM (`comments`)
LEFT JOIN `users` ON `comments`.`user_id` = `users`.`id`
WHERE `comments`.`post_id` = '$post_id'
AND `comments`.`status` = 0
AND `users`.`id` = '$current_user_id'
ORDER BY `comments`.`date` desc

Related

Return only values that have all the necesary relations [duplicate]

In Laravel 4.2, I am trying to achieve a query that returns all users, that have all of certain activities. As of now, I have a query that returns all users that have one of many activities:
//$selectedActivities being an array
$userByActivities = User::with('activities')
->whereHas('activities', function($query) use($selectedActivities){
$query->whereIn('id', $selectedActivities);
})->get();
To be more clear: given activities a,b,c. I am looking for all users that have activity a AND b AND c. My query returns all users that have activity a OR b OR c.
Thank you for your help.
EDIT:
The solution offered by lukasgeiter results in following query:
select * from `users` where
(select count(*) from `activities` inner join `activity_user` on `activities`.`id` = `activity_user`.`activity_id` where `activity_user`.`user_id` = `users`.`id` and `id` = '7') >= 1
and (select count(*) from `activities` inner join `activity_user` on `activities`.`id` = `activity_user`.`activity_id` where `activity_user`.`user_id` = `users`.`id` and `id` = '3') >= 1
and (select count(*) from `activities` inner join `activity_user` on `activities`.`id` = `activity_user`.`activity_id` where `activity_user`.`user_id` = `users`.`id` and `id` = '1') >= 1
and (select count(*) from `activities` inner join `activity_user` on `activities`.`id` = `activity_user`.`activity_id` where `activity_user`.`user_id` = `users`.`id` and `id` = '2') >= 1
Whereas the solution offered by Jarek Tkaczyk:
$userByActivities = User::with('activities')
->whereHas('activities', function($query) use($selectedActivities) {
$query->selectRaw('count(distinct id)')->whereIn('id', $selectedActivities);
}, '=', count($selectedActivities))->get();
for a similar request, results in following query:
select * from `users` where (select count(distinct id) from `activities`
inner join `activity_user` on `activities`.`id` = `activity_user`.`activity_id`
where `activity_user`.`user_id` = `users`.`id` and `id` in ('7', '3', '1', '2')) = 4
You'll have to add multiple whereHas for that:
$query = User::with('activities');
foreach($selectedActivities as $activityId){
$query->whereHas('activities', function($q) use ($activityId){
$q->where('id', $activityId);
});
}
$userByActivities = $query->get();
If you are getting Cardinality violation: 1241 Operand should contain 2 column(s) the problem is the nested selectCount adds to the normal select count(*) instead of overriding the existing select, so changing to $query->distinct()->whereIn('id', $selectedActivities); did the trick for me, or changing to $query->select(DB::raw(count(distinct id)))

how to write a left join for make loop

I want to write this code in one query with left join statement. Currently I use php for loop this query but its not good and is too slow
It's app that have like and dislike option. I want number of every user's like
public function getUserLikedCount($id) {
$query = $this->db->query(
"SELECT * FROM `users`, post, `like`
WHERE users.id = post.post_user_id
AND like.like_post_id = post.post_id
AND users.id = ?
AND post.post_is_active = 1", array($id)
);
return $query->num_rows();
}
thanks
Try like it ( I don't know your table like structure):
$sql = 'SELECT u.id AS `user_id`
COUNT(p.post_id) AS `liked_cnt` <-- or like.id ( if this field exists)
FROM `post` AS p
LEFT JOIN `users` AS u
ON ( u.id = p.post_user_id )
LEFT JOIN `like` AS l
ON ( l.like_post_id = p.post_id )
WHERE p.post_is_active = 1
AND l.status = 1 <-- "liked"
GROUP BY u.id ';
Try this :
$query = $this->db->query(
"SELECT * FROM `users` u
LEFT JOIN post p ON u.id = p.post_user_id AND u.id =?
LEFT JOIN like l ON l.like_post_id = p.post_id AND p.post_is_active = 1
", array($id)

Sort mysqli from a many-to-many table

I'm trying to make a internal web based message system, with a *amp system, primarily for learning purposes. I don't know if this is a trivial topic, but I'm having difficulties so please bear with me.
The goal is to list all the contacts ordered by the last message sent / received.
Currently without sorting it the SQL looks like this
$query = "SELECT username, user.id as user_id,
(SELECT COUNT(message_read)
FROM message_user
WHERE message_read = 0
AND sent_id = user_id
AND receive_id = {$userId}) as unread
FROM user
WHERE user.id IN
(SELECT contact_id FROM allowed_contact WHERE user_id = {$userId})
;";
The structure of the tables are:
The user table has an id,
That links to the message_user table which has a sent_id and a receive_id,
The message_user has a message_id that corresponds to the message.id,
The message table has a timestamp.
I would like this to be done in SQL but if it comes down to PHP I resign to resort to that.
This works.
SELECT `u`.`id` AS user_id, username,
(SELECT COUNT(message_user.message_read)
FROM message_user
WHERE message_user.message_read = 0
AND sent_id = user_id
AND receive_id = {$userId}) as unread
FROM `user` AS `u`
LEFT JOIN `message_user` AS `mu`
ON
(CASE WHEN `u`.`id` != {$userId}
THEN `u`.`id` = `mu`.`sent_id`
WHEN `mu`.`sent_id` = {$userId} AND `mu`.`receive_id` = {$userId}
THEN `u`.`id` = `mu`.`sent_id`
END)
OR
(CASE WHEN `u`.`id` != {$userId}
THEN `u`.`id` = `mu`.`receive_id`
END)
LEFT JOIN `message` AS `m` ON `m`.`id` = `mu`.`message_id`
WHERE u.id IN
(SELECT contact_id FROM allowed_contact WHERE user_id = {$userId})
GROUP BY u.id
ORDER BY MAX(`m`.`timestamp`) DESC;
This broke down the problem I was having.
#Andreas thanks for time and help.
Use 2 LEFT JOIN with a DISTINCT (untested):
SELECT DISTINCT `u`.`id`
FROM `user` AS `u`
LEFT JOIN `message_user` AS `mu` ON `u`.`id` = `mu`.`sent_id` OR `u`.`id` = `mu`.`receive_id`
LEFT JOIN `message` AS `m` ON `m`.`id` = `mu`.`message_id`
ORDER BY `m`.`timestamp` DESC;

SQL + Ion Auth + CodeIgniter?

I have the following SQL:
SELECT (
(SELECT SUM(vote_score)
FROM question_votes
JOIN questions
ON vote_question = q_id
JOIN users
ON q_author = users.id
WHERE q_author` = users.id)
+
(SELECT SUM(vote_score)
FROM answer_votes
JOIN answers
ON vote_answer = a_id
JOIN users
ON a_author = users.id
WHERE a_author = users.id)) AS rep
and I want it to be added here (Ion Auth's method):
$this->db->select(
array(
$this->tables['users'].'.*',
$this->tables['groups'].'.name AS '. $this->db->protect_identifiers('group'),
$this->tables['groups'].'.description AS '. $this->db->protect_identifiers('group_description'),
"(SELECT COUNT(`a_author`) FROM `answers` WHERE a_author = users.id) + (SELECT COUNT(`q_author`) FROM `questions` WHERE q_author = users.id ) AS total_posts",
"SELECT
((SELECT SUM(vote_score)
FROM question_votes
JOIN questions
ON vote_question = q_id
JOIN users
ON q_author = users.id
WHERE q_author` = users.id)
+
(SELECT SUM(vote_score)
FROM answer_votes
JOIN answers
ON vote_answer = a_id
JOIN users
ON a_author = users.id
WHERE a_author = users.id)) AS rep"
)
);
but I get the followin error:
Did you read the error message?
You have a (`) where shouldn't be any.
Change this: WHERE q_author' = users.id for this: WHERE q_author = users.id

how to fetch mysql join results whose id is 0

I have this comment table where users can post comment as well as guest, i can fetch users comments like this
SELECT `comments`.`user_id`, `comments`.`pubdate`, `comments`.`comment`,
`comments`.`guest_name`,
`comments`.`id`,
`users`.`username`,
FROM (`comments`)
JOIN `users` ON `comments`.`user_id` = `users`.`user_id`
WHERE `item_id` = '64' AND `section` = 'blog'
problem is guest users don't have user id hence thier id goes to db as 0 so it is not displayed, how can i show comments of both users and guest ?
You should use LEFT JOIN
SELECT `comments`.`user_id`, `comments`.`pubdate`, `comments`.`comment`,
`comments`.`guest_name`,
`comments`.`id`,
`users`.`username`,
FROM `comments`
LEFT JOIN `users` ON `comments`.`user_id` = `users`.`user_id`
WHERE `item_id` = '64' AND `section` = 'blog'
If there's no matching user for comments.user_id, then users.username will be NULL.
use a left join :
SELECT `comments`.`user_id`, `comments`.`pubdate`, `comments`.`comment`,
`comments`.`guest_name`,
`comments`.`id`,
`users`.`username`,
FROM (`comments`)
LEFT JOIN `users` ON `comments`.`user_id` = `users`.`user_id`
WHERE `item_id` = '64' AND `section` = 'blog'
Do a LEFT JOIN, not a simple one.
SELECT `comments`.`user_id`, `comments`.`pubdate`, `comments`.`comment`,
`comments`.`guest_name`, `comments`.`id`, `users`.`username`
FROM `comments`
LEFT JOIN `users` ON (`comments`.`user_id` = `users`.`user_id`)
WHERE `item_id` = '64' AND `section` = 'blog'

Categories