count a very complex select mysql - php

I have a very complex select that union 3 tables to show customer's last activities.
so:
select c.data, p.user, concat(c.user, ' buy your product') as logs from sell c inner join posts p on c.foto = p.id where p.user = ?
union all
select f.data, c.user, concat(c.user, ' asked you a question') as logs from questions f inner join cadastro c ON f.user = c.id where f.nick = ?
union all
select l.data, l.user, concat(l.user, ' like your product') as logs from likes l inner join posts p on l.post = p.id where p.user = ?
order by data desc
well, each of this tables has a row called SEEN. it is a varchar set with 0 or 1 (0 the user has not seen the message, 1 the user has already seen it).
What I want to add in this query is something to count the rows where seen = 0.
I want to show: YOU HAVE 4 new alerts.
select count(*) will not work and will not count right (the seen set to 1).
What can I do to count all this selects where seen = 0?

Try this
select a.*, SUM(IF(a.seen='0', 1, 0)) as 'unseen_count' FROM (
select c.data, p.user, concat(c.user, ' buy your product') as logs, seen from sell c inner join posts p on c.foto = p.id where p.user = ?
union all
select f.data, c.user, concat(c.user, ' asked you a question') as logs, seen from questions f inner join cadastro c ON f.user = c.id where f.nick = ?
union all
select l.data, l.user, concat(l.user, ' like your product') as logs, seen from likes l inner join posts p on l.post = p.id where p.user = ?
) as a
order by data desc

Related

Need distinct value based on id when we JOIN 4 tables in PHP/MYSQL

Here is my SQL query which joins 4 tables and it works correctly.
SELECT pl.lms_id, u.id, REPLACE(trim(u.`url`), 'www.', '') AS url, trim(u.`name`) as name, p.date_removed, p.status, p.ignore_status FROM `adl_seo_status` p INNER JOIN `adl_user_profiles` u on p.profile_id = u.id INNER JOIN adl_tw_profile_acc_type ac on p.profile_id = ac.profile_id LEFT JOIN `adl_lms_prof_list` pl on u.id = pl.profile_id WHERE u.`vpg_id`='2' AND u.`status` = 'Y' and ac.acc_type_id = '2' ORDER BY u.`url` ASC, p.id DESC
I am facing an issue that, the table adl_seo_status has multiple entries for a single profile_id. So, that accounts are repeating in my listing. I want that account as a single row which means the distinct value of accounts based on profile_id.
You need to use group by, for example:
SELECT
pl.lms_id,
u.id,
REPLACE(trim(u.`url`), 'www.', '') AS url,
trim(u.`name`) AS name,
p.date_removed,
p.status,
p.ignore_status
FROM `adl_seo_status` p INNER JOIN `adl_user_profiles` u ON p.profile_id = u.id
INNER JOIN adl_tw_profile_acc_type ac ON p.profile_id = ac.profile_id
LEFT JOIN `adl_lms_prof_list` pl ON u.id = pl.profile_id
WHERE u.`vpg_id` = '2' AND u.`status` = 'Y' AND ac.acc_type_id = '2'
ORDER BY u.`url` ASC, p.id DESC GROUP BY p.profile_id;

SQL query with count and group by in three tables

I am working on an sql query where I have three tables posts, users and comments. I want to display all posts with its users and number of comments on this. I have following query but it is giving me wrong result:
SELECT
c.userid, count(c.userid), p.postid
FROM comments c, posts p
where c.userid = p.userid group by c.userid
In addition to above query I also require firstname and lastname from users table.
Try something like this,
SELECT
u.userid, u.firstname, u.lastname,p.post, p.postid,
count(c.userid) totalcoments -- may be c.commentid
FROM users u
JOIN posts p ON p.userid=u.userid
LEFT JOIN comments c OM c.postid=p.postid
GROUP BY u.userid, u.firstname, u.lastname,p.post, p.postid
Try something like the following:
SELECT
postid
, p.userid
, COALESCE((
SELECT COUNT( * ) FROM comments WHERE postid = p.id
), 0 ) AS cnt_postid
, COALESCE( ( SELECT CONCAT( firstname, ' ', lastname ) FROM users WHERE userid = p.userid ), 'N/A' ) AS NAME
FROM posts p
LEFT JOIN comments c ON c.postid = p.id
GROUP BY postid
ORDER BY postid
you are probably getting the same amount of count because you not using a group by.
GROUP BY must always be used when using aggregate function. What the group by does is that it will select all unique posts and the the count will return the number of users for that one unique post

select count of rows from 2 tables and merge into one row (mysqli)

i create a web app like facebook by php and mysqli
in my app i have a table for posts , one table for likes , and one table for comments
i want to get the number of comments and likes of each post in one row with his post_id!!!
i try some querys likes this :
select `tblpost`.`post_id`, COALESCE(TCOMM.`comment_num`,0) as `c_num`, COALESCE(TLIKE.`like_num`,0) as `l_num`
from
(select `tblpost`.`post_id`, count(*) as `like_num` from `tblpost` join `tbllikes` on `tbllikes`.`post_id` = `tblpost`.`post_id` group by `tblpost`.`post_id`
) TLIKE
inner join
(select `tblpost`.`post_id`, count(*) as `comment_num` from `tblpost` join `tblcomments` on `tblcomments`.`post_id` = `tblpost`.`post_id` group by `tblpost`.`post_id`) TCOMM
on
TCOMM.`post_id` = TLIKE.`post_id`
but i don't know what's my problem
You can do count distincts with two left joins.
Something like this would work if there are fields like_id and comment_id in the tables tbllikes and tblcomments
SELECT
tblpost.post_id AS post_id,
COUNT(DISTINCT tbllikes.like_id) AS likes,
COUNT(DiSTINCT tblcomments.comment_id) AS comments
FROM tblpost
LEFT JOIN tbllikes ON tbllikes.post_id = tblpost.post_id
LEFT JOIN tblcomments on tblcomments.post_id = tblpost.post_id
GROUP BY tblpost.post_id
First, I think you can greatly simplify your query:
select l.post_id,
COALESCE(c.comment_num, 0) as c_num, COALESCE(l.like_num, 0) as l_num
from (select l.post_id, count(*) as like_num
from tbllikes l
group by l.post_id
) l inner join
(select c.post_id, count(*) as comment_num
from tblcomments c
group by c.post_id
) c
on l.post_id = c.post_id;
This will only get you posts that have both likes and comments. To get what you want, use a left join:
select p.post_id,
COALESCE(c.comment_num, 0) as c_num, COALESCE(l.like_num, 0) as l_num
from tblpost p left join
(select l.post_id, count(*) as like_num
from tbllikes l
group by l.post_id
) l
on l.post_id = p.post_id left join
(select c.post_id, count(*) as comment_num
from tblcomments c
group by c.post_id
) c
on c.post_id = p.post_id;

MySQL Query left join repeated records

With a Left Join i have this result.
Here the screen
http://f.cl.ly/items/373Y141r1K131d0n3f1q/Schermata%202013-04-01%20alle%2016.51.18.png
i want to show only record once time, without repeat it, but with a left join all my records are different.
what i have to do for show once all my records?
the query.
SELECT * FROM login_users
LEFT JOIN login_users_seguaci
ON login_users.user_id = login_users_seguaci.following
WHERE name LIKE ""
AND user_id != '1'
ORDER BY data DESC
SELECT x.*, y.*
FROM login_users x
LEFT JOIN
(
SELECT a.*
FROM login_users_seguaci a
INNER JOIN
(
SELECT following, MAX(DATA) max_data
FROM login_users_seguaci
GROUP BY following
) b ON a.following = b.following AND
a.DATA = b.max_date
) y ON x.user_id = y.following
// WHERE ... your condition here ...
ORDER BY t.data DESC

MYSQL query check if user like

I'm asking for query statement I have two tables
first table 'posts' :
post_id title Userid
1 test 1
The other table is 'likes'
userid post_id
1 1
I need single query to check if user like this photo or not in bulk select my solution is very poor :
SELECT * FROM `table` WHERE x = x LIMIT 100;
and give it foreach and make query for every row :
foreach($results as $v)
{
$data[1] = $v;
$data[1]['is_like'] = SELECT COUNT(*) FROM likes WHERE userid = 1;
}
1 is the already login user id
I need to single query to return post_id,.. etc and filed like is_like
Assuming likes can have only 1 row with the same (user_id,post_id) :
SELECT p.* ,
CASE WHEN
l.id IS NULL THEN 0
ELSE 1
END as is_liked
FROM posts p
LEFT JOIN likes l ON l.user_id = p.user_id and l.post_id =p.post_id
If not (multiple rows in likes for a given (user_id,post_id) ) :
SELECT p.* ,
CASE WHEN
l.user_id IS NULL THEN 0
ELSE 1
END as is_liked
FROM posts p
LEFT JOIN
(
SELECT DISTINCT user_id,post_id FROM likes
) l ON l.user_id = p.user_id and l.post_id =p.post_id;
Or
SELECT p.* ,
CASE
WHEN EXISTS (SELECT NULL FROM likes l
WHERE l.user_id = p.user_id and l.post_id =p.post_id) THEN 1
ELSE 0
END as is_liked
FROM posts p
Update
I hope I got a better understanding of the question now. My assumption : posts.user_id is id of user who created post; like table stores information about who likes the post. Thus, to check all posts and whether a particular like them you need ($login_user_id should be escaped properly)
SELECT p.* ,
CASE
WHEN EXISTS (SELECT NULL FROM likes l
WHERE l.user_id = $login_user_id and l.post_id =p.post_id) THEN 1
ELSE 0
END as is_liked
FROM posts p
SELECT
p.post_id,
p.title,
IF(l.post_id IS NOT NULL,1,0) as like
FROM posts as p
LEFT JOIN likes as l ON l.post_id = p.post_id AND l.userid = p.userid
WHERE p.Userid = 1
If post_id in likes table is available it will return 1 else 0.
Something like this should work as a single query (untested, of course - you didn't provide much data to use for testing):
select
p.title, count(l.post_id)
from
`posts` p
inner join
`likes` l
on
l.userid = p.userid and l.post_id = p.post_id
where
p.userid = loggedinuserID
group by
p.userid
This will give you a count of the total posts the specified user has liked.

Categories