how to inner join three tables and get count - php

I have three tables:
members (id, name, surname, usr_img)
user_uploads (imgID, user_id, filename, description, up_time)
img_likes (likeID, img_id, user_id)
I need to get all from user_uploads, and using the img_id, get uploader info from members and make 2 counts in the img_likes table (check if user_id (from session variable) and img_id exists and get the img total likes).
SELECT user_uploads.* AS uu, members.*, COUNT(img_id, user_id) AS usr_liked, COUNT(img_id) AS total_likes
FROM user_uploads
INNER JOIN members AS m ON m.id = uu.user_id -- owner info
INNER JOIN img_likes AS il ON il.img_id = uu.imgID AND il.user_id = ? -- check if logged in user already liked
INNER JOIN img_likes AS ilt ON ilt.img_id = uu.imgID -- total likes
GROUP BY img_id, user_id
ORDER BY up_time DESC
I don't need to get nothing from img_id, just count the number of rows. I don't know if an inner join is necessary, maybe to specify the user_id?
and to get the counts:
$usr_liked = row['usr_liked'];
$total_likes = rwo['total_likes'];
Will that work?
EDIT: add new query:
SELECT
user_uploads.*,
(
SELECT *
FROM members m
WHERE m.id = user_uploads.user_id
),
(
SELECT COUNT(*)
FROM img_likes t
WHERE t.img_id = user_uploads.imgID AND t.user_id = ?
) AS user_likes,
(
SELECT COUNT(*)
FROM img_likes t
WHERE t.img_id = user_uploads.imgID
) AS total_likes
FROM user_uploads
ORDER BY up_time DESC

You could use subquery:
SELECT
uu.*,
m.*,
(
SELECT COUNT(t.*)
FROM img_likes t
WHERE t.img_id = uu.imgID AND t.user_id = ?
) AS user_likes,
(
SELECT COUNT(t.*)
FROM img_likes t
WHERE t.img_id = uu.imgID
) AS total_likes
FROM
user_uploads AS uu
INNER JOIN members AS m ON
m.id = uu.user_id
ORDER BY
uu.up_time DESC

Related

SELECT posts, its last 3 comments and count of all comments

SELECT posts, its last 3 comments and count of all comments
My code:
SELECT p.*, u.id, u.username username, u.usersurname usersurname, u.usermainphoto userphoto, GROUP_CONCAT(c.text SEPARATOR 'a!k#h#md%o^v&') commenttext,GROUP_CONCAT(c.likes SEPARATOR '-') commentlikes,GROUP_CONCAT(c.dislikes SEPARATOR '-') commentdislikes, GROUP_CONCAT(c.commentdate) commentdate, GROUP_CONCAT(u2.username) commentauthorname, GROUP_CONCAT(c.anonim) commentanonym, GROUP_CONCAT(c.id) commentid, GROUP_CONCAT(u2.id) commentauthorid, GROUP_CONCAT(u2.usersurname) commentauthorsurname, GROUP_CONCAT(u2.usermainphoto) commentauthorphoto, GROUP_CONCAT(c.commentphotoid) commentphotoid
FROM posts p
LEFT JOIN comments c ON c.post = p.postid AND c.commentdel=0
LEFT JOIN users u ON u.id = p.postauthorid
LEFT JOIN users u2 ON u2.id = c.author
WHERE p.postwallid = :id AND p.postdel=0
GROUP BY postid
ORDER BY postid DESC
it gives me all comments, but I need only 3
You need a timestamp or counter of something to determine which comments are the three you want. Add that column name between the angle brackets below.
SELECT p.*, u.id, u.username username, u.usersurname usersurname, u.usermainphoto userphoto, GROUP_CONCAT(c.text SEPARATOR 'a!k#h#md%o^v&') commenttext,GROUP_CONCAT(c.likes SEPARATOR '-') commentlikes,GROUP_CONCAT(c.dislikes SEPARATOR '-') commentdislikes, GROUP_CONCAT(c.commentdate) commentdate, GROUP_CONCAT(u2.username) commentauthorname, GROUP_CONCAT(c.anonim) commentanonym, GROUP_CONCAT(c.id) commentid, GROUP_CONCAT(u2.id) commentauthorid, GROUP_CONCAT(u2.usersurname) commentauthorsurname, GROUP_CONCAT(u2.usermainphoto) commentauthorphoto, GROUP_CONCAT(c.commentphotoid) commentphotoid
FROM posts p
LEFT JOIN comments c ON c.post = p.postid AND c.commentdel = 0
LEFT JOIN users u ON u.id = p.postauthorid
LEFT JOIN users u2 ON u2.id = c.author
WHERE p.postwallid = :id AND p.postdel = 0
and (
select count(*) from comments as c2
where c2.postid = p.postid and c2.commentdel = 0
and c2.<timestamp> <= c.timestamp
) < 3
GROUP BY postid
ORDER BY postid DESC
Edit: I didn't add the count of all comments. I think you can easily add it with another subquery in the select list but I know MySQL people don't like subqueries very much.
(
select count(*) from comments as c2
where c2.postid = c.postid and c2.commentdel = 0
) as comment_count
I add in SELECT count(postid) as all_comments and at the end LIMIT 0, 3
SELECT count(postid) as all_comments, p.*, u.id, u.username username, u.usersurname usersurname, u.usermainphoto userphoto, GROUP_CONCAT(c.text SEPARATOR 'a!k#h#md%o^v&') commenttext,GROUP_CONCAT(c.likes SEPARATOR '-') commentlikes,GROUP_CONCAT(c.dislikes SEPARATOR '-') commentdislikes, GROUP_CONCAT(c.commentdate) commentdate, GROUP_CONCAT(u2.username) commentauthorname, GROUP_CONCAT(c.anonim) commentanonym, GROUP_CONCAT(c.id) commentid, GROUP_CONCAT(u2.id) commentauthorid, GROUP_CONCAT(u2.usersurname) commentauthorsurname, GROUP_CONCAT(u2.usermainphoto) commentauthorphoto, GROUP_CONCAT(c.commentphotoid) commentphotoid
FROM posts p
LEFT JOIN comments c ON c.post = p.postid AND c.commentdel=0
LEFT JOIN users u ON u.id = p.postauthorid
LEFT JOIN users u2 ON u2.id = c.author
WHERE p.postwallid = :id AND p.postdel=0
GROUP BY postid
ORDER BY postid DESC
LIMIT 0, 3

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;

How to JOIN these 3 tables

I have the following JOIN query already done:
$stmt = $cxn->prepare('SELECT p.post_id, p.reply_to, p.parent_id, p.post_path, p.user_id, p.content, p.datetime, p.total_likes, p.total_replies, p.total_reposts, u.username, u.display_name FROM posts p LEFT JOIN users u ON p.user_id = u.user_id WHERE p.user_id IN (SELECT following_id FROM follows WHERE user_id = ?) AND p.removed != 1 ORDER BY p.datetime DESC LIMIT 26');
$stmt->bind_param('i', $user_info[0]);
$stmt->execute();
I have another query that's only purpose is to check if a row exists or not:
$stmt = $cxn->prepare('SELECT COUNT(like_id) FROM likes WHERE post_id = ? AND user_id = ?');
$stmt->bind_param('ii', $row['post_id'], $user_info[0]); // $row['post_id'] is the value of p.post_id from the first query
$stmt->execute();
How would I join the second query into the first one? I've never joined 3 tables so I'm unsure of the procedure.
Thanks.
Joining three tables in a query is like joining two, except... you join three.
Basically it would go something like this:
SELECT p.post_id (...), u.username (...), COUNT(l.like_id) AS nbOfLikes
FROM posts p
LEFT JOIN users u ON p.user_id = u.user_id
LEFT JOIN likes l ON l.post_id = p.post_id AND l.user_id = u.user_id
WHERE p.user_id IN
(SELECT following_id
FROM follows
WHERE user_id = ?)
AND p.removed != 1
ORDER BY p.datetime DESC
LIMIT 26;
-- Actually I think a UNION would perhaps be more adapted to your need concerning the likes table.
If you always have the user_id filled into your table posts and it's a foreign key, avoid to use a left join statement, you can get a better performance using join statement. To join 3 or more tables you can just add the join statement:
SELECT
p.post_id
, p.reply_to
, p.parent_id
, p.post_path
, p.user_id
, p.content
, p.datetime
, p.total_likes
, p.total_replies
, p.total_reposts
, u.username
, u.display_name
FROM posts p
JOIN users u ON p.user_id = u.user_id WHERE p.user_id IN (SELECT following_id FROM follows
JOIN TABLE_2 ON TABLE_2.id = posts.TABLE_id
JOIN TABLE_3 ON TABLE_3.id = posts.TABLE_id
...
WHERE
user_id = ?)
AND p.removed != 1
ORDER BY p.datetime DESC
LIMIT 26

Laravel Query Builder

I'm new on laravel.
How do I run this query on laravel?
SELECT a.id, active, name, email, IFNULL(b.Total, 0) AS leads
FROM users AS a
LEFT JOIN (
SELECT user_id, count(*) as Total
FROM lead_user
GROUP BY user_id
) AS b
ON a.id= b.user_id
WHERE is_deleted = 0
Thanks!
well, since you have the query already written...
DB::statement('
SELECT a.id, active, name, email, IFNULL(b.Total, 0) AS leads
FROM users AS a
LEFT JOIN (
SELECT user_id, count(*) as Total
FROM lead_user
GROUP BY user_id
) AS b
ON a.id= b.user_id
WHERE is_deleted = 0
');
Here are the docs

How to store/process multiple tables's data using MySql and PHP

I have 5 different MySql tables viz:
u_t (uid, pwd, field1, field2)
t_1 (tid_1, ut_uid, field_1, field_2, points)
t_2 (tid_2, ut_uid, field_1, field_2, points)
t_3 (tid_3, ut_uid, field_1, field_2, points)
t_4 (tid_4, ut_uid, field_1, field_2, points)
PS: uid=pk , tid_1,2,3,4=pk, ut_uid=fk
All the above tables are having some information based on some unique features.
Now i want to get the sum of points from each table for every user for storing and displaying purpose, using PHP.
try
select u_t.uid,
sum(t_1.points+t_2.points+t_3.points+t_4.points+t_5.points) as total_p
from u_t
left outer join t_1 on t_1.ut_uid = u_t.uid
left outer join t_2 on t_2.ut_uid = u_t.uid
left outer join t_3 on t_3.ut_uid = u_t.uid
left outer join t_4 on t_4.ut_uid = u_t.uid
group by u_t.uid
An uglier version of this:
SELECT ut.uid, sum(t1.pts + t2.pts + t3.pts + t4.pts) total
FROM u_t ut
LEFT JOIN
(
SELECT ut_uid, sum(points) pts
FROM t_1
GROUP BY ut_uid
) t1
on ut.uid = t1.ut_uid
LEFT JOIN
(
SELECT ut_uid, sum(points) pts
FROM t_2
GROUP BY ut_uid
) t2
on ut.uid = t2.ut_uid
LEFT JOIN
(
SELECT ut_uid, sum(points) pts
FROM t_3
GROUP BY ut_uid
) t3
on ut.uid = t3.ut_uid
LEFT JOIN
(
SELECT ut_uid, sum(points) pts
FROM t_4
GROUP BY ut_uid
) t4
on ut.uid = t4.ut_uid
GROUP BY ut.uid

Categories