How to select the max table from join table? - mysql

I have table name posts and another table which name is counttbl
In my post table there is column name
postid(primarykey), postdetails, postdate(timestamp)
And in counttbl there are 3 column which are
id(primarykey), postid,countnumber
I want to select that post from counttbl which has maximumnumber of count,
E.g. in post table I have
postid = 1, postdetails = details1, date = 29:11:00 00:00:00
And in count there is postid = 1, countnumber = 4, and postid = 2, countnumber = 3
Then I want to select that post which has maximumber count number and show that post details using join.

This statement would give you the desired result.
I named the tables and fields differen because of possible conflicts with reserved words in SQL.
SELECT * FROM
(
SELECT counts.postid, counts.counts
FROM counts
WHERE counts.counts = (SELECT max(counts) FROM counts)
) tempcounts
INNER JOIN posts ON posts.postid = tempcounts.postid
ORDER BY posts.postdate DESC limit 0,1
If more post have the same count they all will be in the result

Please use below query:
SELECT MAX(cnt.countnumber), cnt.postid
FROM counttbl as cnt
JOIN post as pst ON cnt.postid = pst.id
I have given table name:
Table name: post and counttbl

You can try below
select * from posts p
inner join
(
select postid, max(countnumber) from counttbl group by postid
) as p1
on p.postid=p1.postid

try this:
select * from post where postid in (select postid from counttbl having max(countnumber));

try this
select * from posts WHERE post_id IN (select MAX(countnumber) from counttble )

Related

SQL Left Join Problem (All lines is not coming)

The tables are as below:
Users Table (Table Name: users) :
[users table]
Friends Table (Table Name: friends) :
[friends table]
My Sql Code:
SELECT
friend_id,
friend_adding_id,
friend_added_id,
user_id,
user_name
FROM friends
LEFT JOIN users ON friends.friend_added_id = users.user_id
WHERE
friend_adding_id = 1
OR friend_added_id = 1
AND friend_confirm = 1
ORDER BY friends.friend_id DESC
LIMIT 1, 10
Leaving the column below:
[Leaving column]
How can I fix this missing query? Please help me.
first you are missing a row not a column or not a query, second its because of and /or priorities. And has higher priority than OR , for you logic to work properly, you have to give Or higher priority by using parenthesis:
SELECT
friend_id,
friend_adding_id,
friend_added_id,
user_id,
user_name
FROM friends
LEFT JOIN users ON friends.friend_added_id = users.user_id
WHERE
(friend_adding_id = 1 OR friend_added_id = 1) -- < like this
AND friend_confirm = 1
ORDER BY friends.friend_id DESC
LIMIT 1, 10

How to add the number of rows of the first table to another with the condition

There are two tables:
####comments#### ####news######
#cid#news_id# #id##comm_num#
#1##1# #1###2#
#2##1# #2###1#
#3##2# #3###3#
I try to count and put the number of comments from the table 'comments' into the table 'news', but I get the wrong result. Why?
UPDATE news JOIN comments ON news.id = comments.news_id SET
news.comm_num = ( SELECT COUNT( * )
FROM comments WHERE comments.news_id > 123)
WHERE news.id > 123
'comments.news_id' = 'id' of commented news from table 'news'
I wrote a working solution for particular cases, but I can’t figure out how to make a request with a condition larger than.
UPDATE news a
SET comm_num = (SELECT COUNT(*)
FROM comments c
WHERE c.news_id = 123)
WHERE a.id = 123
Simply use a correlated subquery:
UPDATE news n
SET comm_num = (SELECT COUNT(*)
FROM comments c
WHERE c.news_id = n.id
) ;
I am not sure what the condition WHERE news.id > 123 is for.
You can get the count of total comments on a news using a Derived Table. Join this back to the news table on the news_id and update the values accordingly.
We use LEFT JOIN to handle the case where there is no comments on a news. And, Coalesce() function is used to change null to 0 (in case of no comments).
UPDATE news a
LEFT JOIN (SELECT news_id, COUNT(*) AS comm_num
FROM comments
GROUP BY news_id) b
ON b.news_id = a.id
SET a.comm_num = COALESCE(b.comm_num,0)
If you want to update only those news where id is more than 123; you can add the conditions as follows:
UPDATE news a
LEFT JOIN (SELECT news_id, COUNT(*) AS comm_num
FROM comments
WHERE news_id > 123 -- add condition to Derived Table
GROUP BY news_id) b
ON b.news_id = a.id
WHERE a.id > 123 -- add condition here also to avoid updating id <= 123
SET a.comm_num = COALESCE(b.comm_num,0)

MySql throws error Subquery returns more than 1 row

I want to retrieve values from 3 table where i am getting error "Sub query returns more than 1 row " .
My concept is to retrieve all the post where i have to calculate the sum of votes from ttpostvotes table with respect to each post and if provided userid is voted for the that post then it will shows the post count like 1 or -1.
My query is as below:
SELECT r.PostId, r.`Post`,r.PostTime, coalesce(x.Votes, 0) as Votes ,
(Select Votes From `ttpostvotes` where UserId=30 and x.PostId=r.PostId ) as IsUservoted,
(Select Count(*) From ttreply where PostId=r.PostId ) AS ReplyCount FROM `ttpost` r
left join ( SELECT PostId, sum(Votes) as Votes FROM `ttpostvotes` GROUP BY PostId ) x ON
x.PostId = r.PostId WHERE r.OffensiveCount<3 and r.SpamCount<5 and r.OtherCount<7 and r.`PeekId`=101 ORDER BY `r`.`PostTime` DESC
The 3 tables are like as below:
ttpost
ttpostvotes
ttreply
This is your select:
SELECT r.PostId, r.`Post`,r.PostTime, coalesce(x.Votes, 0) as Votes,
(Select Votes From `ttpostvotes` where UserId = 30 and x.PostId = r.PostId
) as IsUservoted,
(Select Count(*) From ttreply where PostId=r.PostId ) AS ReplyCount
The first subquery has no aggregation, so I suppose a user could vote more than once for a post. This will fix the syntax error:
SELECT r.PostId, r.`Post`,r.PostTime, coalesce(x.Votes, 0) as Votes,
(Select SUM(Votes) From `ttpostvotes` where UserId = 30 and x.PostId = r.PostId
) as IsUservoted,
(Select Count(*) From ttreply where PostId = r.PostId ) AS ReplyCount
Whether it does what you want is a different question.
Note: if you want your original query to work, you should define a unique constraint/index on ttpostvotes:
create unique index unq_ttpostvotes_userid_postid on ttpostvotes(userid, postid);

How to select all this data without repeating subqueries?

Say I have a table called 'users', a table called 'posts' and a table called 'ratings', that stores the rating of each user to each post. If I wanted to select the posts, together with their thumbs up, thumbs down and 'average' ratings (rounded to the second decimal), I would do:
SELECT *,
(SELECT COUNT(*) FROM ratings WHERE thumb='up' AND post_id = posts.id) AS thumbs_up,
(SELECT COUNT(*) FROM ratings WHERE thumb='down' AND post_id = posts.id) AS thumbs_down,
ROUND((SELECT COUNT(*) FROM ratings WHERE thumb='up' AND post_id = posts.id) / (SELECT COUNT(*) FROM ratings WHERE post_id = posts.id), 2) AS average_rating
FROM posts;
But is there a way to obtain this same data without repeating the subqueries? I mean, ideally I would like to do:
SELECT *,
(SELECT COUNT(*) FROM ratings WHERE thumb='up' AND post_id = posts.id) AS thumbs_up,
(SELECT COUNT(*) FROM ratings WHERE thumb='down' AND post_id = posts.id) AS thumbs_down,
ROUND(thumbs_up / (thumbs_up + thumbs_down), 2) AS average_rating
FROM posts;
But MySQL does not allow this. What is next best thing? Or is there an even better way, by using JOINs or UNIONs?
SELECT
*,
ROUND(thumbs_up / (thumbs_up + thumbs_down), 2) AS average_rating
FROM (
SELECT
YourColumns...
SUM(CASE WHEN r.thumb = 'up' THEN 1 END) AS thumbs_up,
SUM(CASE WHEN r.thumb = 'down' THEN 1 END) AS thumbs_down
FROM
posts p LEFT JOIN
ratings r ON r.post_id = p.id
GROUP BY YoursColumns
) sub
Why not having in your "posts" table a column "ups" and "downs" where are summarized / counted the ups and downs ? you would end with something like this :
SELECT ups, downs, ROUND(ups / (ups + downs), 2) AS average_rating FROM posts where id = anId;
You could simply use variables inside a stored procedure. Code is concept and may need adjustment to fit mysql.
SET #thumbsup = 0;
SET #thumbsdown = 0;
SELECT #thumbsup = COUNT( * ) FROM ratings WHERE thumb = 'up' AND post_id = #someid;
SELECT #thumbsdown = COUNT( * ) FROM ratings WHERE thumb = 'down' AND post_id = #someid;
RETURN #thumbsup, #thumbsdown, ROUND( #thumbsup / ( thumbsup + thumbsdown ), 2 );

MySQL - How to count number of rows from primary query, ignore subquery rows?

I use the following MySQL to return a list of posts and their corresponding comments.
SELECT *
FROM forum_qa
JOIN user_profiles
ON user_id = forum_qa_author_id
LEFT JOIN (SELECT forum_cm_id,
forum_cm_author_id,
forum_qa_id_fk,
forum_cm_text,
FROM forum_cm
JOIN user_profiles
ON user_id = forum_cm_author_id) AS c
ON forum_qa_id = c.forum_qa_id_fk
WHERE forum_qa_parent_id = $forum_qa_id
If I run
$data['num_answers'] = $query->num_rows();
This allows me to get the number of returned rows and pass the array to my controller and view.
But this is returning all rows (posts + comments). So if 1 post has 10 comments, it returns 10.
How could I have this query count only the number of posts (ie, returning 1) not including the subquery?
Each post has a unique id saved in forum_qa.forum_qa_id
Each comment has a unique id saved in forum_cm.forum_cm_id.
Thanks for helping -- will post more code if needed.
Not the fastest, but you are not restricted in using GROUP BY:
SELECT *,
(SELECT COUNT(*) FROM forum_qa WHERE forum_qa_parent_id = $forum_qa_id) Cnt
FROM forum_qa
JOIN user_profiles
ON user_id = forum_qa_author_id
LEFT JOIN (SELECT forum_cm_id,
forum_cm_author_id,
forum_qa_id_fk,
forum_cm_text,
FROM forum_cm
JOIN user_profiles
ON user_id = forum_cm_author_id) AS c
ON forum_qa_id = c.forum_qa_id_fk
WHERE forum_qa_parent_id = $forum_qa_id
You can run another query or add one more column (with an independent subquery) in the result set:
SELECT *
, ( SELECT COUNT(*)
FROM forum_qa
WHERE forum_qa_parent_id = $forum_qa_id
) AS cntPosts
FROM forum_qa
JOIN user_profiles
ON user_id = forum_qa_author_id
LEFT JOIN (SELECT forum_cm_id,
forum_cm_author_id,
forum_qa_id_fk,
forum_cm_text,
FROM forum_cm
JOIN user_profiles
ON user_id = forum_cm_author_id) AS c
ON forum_qa_id = c.forum_qa_id_fk
WHERE forum_qa_parent_id = $forum_qa_id
COUNT(DISTINCT forum_qa.forum_qa_id)
COUNT(DISTINCT col_name) counts the distinct post ids. This should equal the number of posts.