I'm using two tables in the database:
The "members" table:
id | name
-----------------------
1 | John
2 | Mike
3 | Jane
4 | Marry
The "messages" table:
message_id | text | from | to
---------------------------------------------
1 | text 1 | 1 | 2
2 | text 2 | 1 | 3
3 | text 3 | 1 | 4
4 | text 4 | 2 | 1
5 | text 5 | 1 | 2
I need to get as a result grouped messages sent by a specific user, sorted by the last message sent and count the total number of sent messages to specific user.
My current mysql query looks:
SELECT max(messages.message_id) as max_mess, messages.from, messages.to, members.name, messages.text
FROM messages INNER JOIN members on members.id = messages.to
WHERE messages.from = '1'
GROUP BY messages.from
ORDER BY max_mess DESC
Required result should look like:
max_mess | from | to | name | text | total_messages
--------------------------------------------------------------------
5 | 1 | 2 | Mike | text 5 | 3
3 | 1 | 4 | Marry | text 3 | 1
2 | 1 | 3 | Jane | text 2 | 1
Is it possible to do that using only one mysql query and what should be changed in the current query?
You can use one of the following solutions:
solution #1 (using a additional JOIN):
SELECT
m1.max_mess,
m1.from,
m1.to,
m1.name,
m2.text,
m1.total_messages
FROM (
SELECT
MAX(message_id) AS max_mess,
messages.from,
messages.to,
members.name,
COUNT(message_id) AS total_messages
FROM messages INNER JOIN members ON members.id = messages.to
WHERE messages.from = 1
GROUP BY messages.from, messages.to
) m1 LEFT JOIN messages m2 ON m1.max_mess = m2.message_id
ORDER BY m1.max_mess DESC;
demo: http://sqlfiddle.com/#!9/7c73b6/1/0
Note: This solution should be faster than the second solution. You can find more details on the following answer on StackOverflow: JOIN vs. Sub-Query.
solution #2 (using a sub-select):
SELECT
MAX(message_id) AS max_mess,
m1.from,
m1.to,
members.name,
(SELECT messages.text FROM messages WHERE message_id = MAX(m1.message_id)) as text,
COUNT(message_id) AS total_messages
FROM messages m1 INNER JOIN members ON members.id = m1.to
WHERE m1.from = 1
GROUP BY m1.from, m1.to
ORDER BY max_mess DESC;
demo: http://sqlfiddle.com/#!9/7c73b6/2/0
This is one query. If you want to remove the JOIN statement then you should use
SELECT max(messages.message_id) as max_mess, messages.from, messages.to, members.name, messages.text
FROM messages, members
WHERE messages.from = '1' AND members.id = messages.to
GROUP BY messages.from
ORDER BY max_mess DESC
i think you are searching for this:
SELECT MAX(messages.message_id) AS max_mess, messages.from, messages.to, members.name, messages.text,, SUM(`from`) total_messages
FROM messages INNER JOIN members ON members.id = messages.to
WHERE messages.from = '1'
GROUP BY messages.from,messages.to
ORDER BY max_mess DESC;
Related
I have Three tables
1)review_trans
2)user_comment_trans
3)helpful_review_trans
The table structure looks like this
review_trans
review_id(pk) | review_desc | user_id
--------------+----------------+-----------
1 | hello world | 1
2 | test2 | 1
3 | test3 | 2
user_comment_trans
comment_id | review_id | user_id
------------+--------------+------------
1 | 1 | 4
2 | 1 | 2
3 | 2 | 3
helpful_review_trans
helpful_review_id | review_id | user_id
------------------+------------+------------
1 | 1 | 4
2 | 1 | 2
3 | 2 | 3
I want count on each review for helpful votes and comments.
So output i want is like this
OUTPUT
review_id review_desc count(helpful_review_id) count(comment_id)
------------+------------------+----------------------------+--------------------
1 | hello world | 2 | 2
2 | test2 | 1 | 1
3 | test3 | |
Iam unable to get this record.I tried joining the tables but it only shows just one review_desc
Please advise and help.
Use left join with count(distinct)
select r.review_id,
r.review_desc,
count(distinct u.comment_id),
count(distinct h.helpful_review_id)
from review_trans r
left join user_comment_trans u on(r.review_id = u.review_id)
left join helpful_review_trans h on(r.review_id = h.review_id)
group by r.review_id
Demo
SELECT rt.review_id, rt.review_desc,
COUNT(DISTINCT hrt.helpful_review_id), COUNT(DISTINCT uct.comment_id)
FROM review_trans rt
LEFT JOIN helpful_review_trans hrt ON rt.review_id = hrt.review_id
LEFT JOIN user_comment_trans uct ON uct.review_id = rt.review_id
GROUP BY rt.review_id
SELECT rt.review_id, rt.review_desc, helpful_count, comment_count
FROM review_trans AS rt
LEFT JOIN (
SELECT review_id, COUNT(*) AS comment_count
FROM user_comment_trans
GROUP BY review_id) AS uct ON rt.review_id = uct.review_id
LEFT JOIN (
SELECT review_id, COUNT(*) AS helpful_count
FROM helpful_review_trans
GROUP BY review_id) AS hrt ON rt.review_id = hrt.review_id
You could do this:
SELECT
review_trans.review_id,
review_trans.review_desc,
(
SELECT
COUNT(*)
FROM
helpful_review_trans
WHERE
helpful_review_trans.review_id=review_trans.review_id
) AS helpful_review_id,
(
SELECT
COUNT(*)
FROM
user_comment_trans
WHERE
user_comment_trans.review_id=review_trans.review_id
) AS CountComment_id
FROM
review_trans
First at all i am nood into SQL thing, Now i am working on a class project where
I have some tables like
Table user
user_id | username | name
1 | nihan | Nihan Dip
2 | dip | Meaw ghew
more | more | more
Table Friend
you | friend_id
1 | 2
1 | 27
2 | 9
more | more
Table Follow
user_id | follows
1 | 99
7 | 34
Table post
post_id | user_id | type | content | post_time
1 | 1 | text | loren toren | timestamp
2 | 2 | text | ipsum | timestamp
Now i want to get post by users friend and who he follows and offcourse his so i made this SQL
SELECT
username, name,content, post_time
FROM
post
INNER JOIN
user ON user.user_id = post.user_id
WHERE
post.user_id IN (SELECT
friend_id
FROM
friend
WHERE
you = 1
UNION ALL
SELECT
follows
FROM
follow
WHERE
user_id = 1)
OR post.user_id = 1
ORDER BY post_time DESC
LIMIT 10
this query works just fine. I just wanted to know is there anymore optimization could be done? Then how? Please teach me :)
Instead of using IN try it with JOIN add add few more indexes.
SELECT DISTINCT u.name, u.username,
p.content, p.post_time
FROM post p
INNER JOIN user u
ON u.user_id = p.user_id
INNER JOIN
(
SELECT friend_id id
FROM friend
WHERE you = 1
UNION ALL
SELECT follows id
FROM follow
WHERE user_id = 1
) s ON p.user_id = s.ID
ORDER BY post_time DESC
LIMIT 10
I'm trying to build a commenting system on my website but having issues with ordering the comments correctly. This is a screenshot of what I had before it went wrong:
And this is the query before it went wrong:
SELECT
com.comment_id,
com.parent_id,
com.is_reply,
com.user_id,
com.comment,
com.posted,
usr.username
FROM
blog_comments AS com
LEFT JOIN
users AS usr ON com.user_id = usr.user_id
WHERE
com.article_id = :article_id AND com.moderated = 1 AND com.status = 1
ORDER BY
com.parent_id DESC;
I now want to include each comment's votes from my blog_comment_votes table, using a LEFT OUTER JOIN, and came up with this query, which works, but screws with the order of results:
SELECT
com.comment_id,
com.parent_id,
com.is_reply,
com.user_id,
com.comment,
com.posted,
usr.username,
IFNULL(c.cnt,0) votes
FROM
blog_comments AS com
LEFT JOIN
users AS usr ON com.user_id = usr.user_id
LEFT OUTER JOIN (
SELECT comment_id, COUNT(vote_id) as cnt
FROM blog_comment_votes
GROUP BY comment_id) c
ON com.comment_id = c.comment_id
WHERE
com.article_id = :article_id AND com.moderated = 1 AND com.status = 1
ORDER BY
com.parent_id DESC;
I now get this order, which is bizarre:
I tried adding a GROUP BY clause on com.comment_id but that failed too. I can't understand how adding a simple join can alter the order of results! Can anybody help back on the correct path?
EXAMPLE TABLE DATA AND EXPECTED RESULTS
These are my relevant tables with example data:
[users]
user_id | username
--------|-----------------
1 | PaparazzoKid
[blog_comments]
comment_id | parent_id | is_reply | article_id | user_id | comment
-----------|-----------|----------|------------|---------|---------------------------
1 | 1 | | 1 | 1 | First comment
2 | 2 | 1 | 1 | 20 | Reply to first comment
3 | 3 | | 1 | 391 | Second comment
[blog_comment_votes]
vote_id | comment_id | article_id | user_id
--------|------------|------------|--------------
1 | 2 | 1 | 233
2 | 2 | 1 | 122
So the order should be
First comment
Reply to first comment +2
Second Comment
It's difficult to say without looking at your query results, but my guess is that it's because you are only ordering by parent id and not saying how to order when two records have the same parent id. Try changing your query to look like this:
SELECT
com.comment_id,
com.parent_id,
com.is_reply,
com.user_id,
com.comment,
com.posted,
usr.username,
COUNT(c.votes) votes
FROM
blog_comments AS com
LEFT JOIN
users AS usr ON com.user_id = usr.user_id
LEFT JOIN
blog_comment_votes c ON com.comment_id = c.comment_id
WHERE
com.article_id = :article_id AND com.moderated = 1 AND com.status = 1
GROUP BY
com.comment_id,
com.parent_id,
com.is_reply,
com.user_id,
com.comment,
com.posted,
usr.username
ORDER BY
com.parent_id DESC, com.comment_id;
I have two tables :
users:
___________________________
|user_id | username |
|_______________|___________|
| 1 | Dolly |
| 2 | Didi |
|_______________|___________|
forum:
_____________________________________________________________
|match_static_id| comment | timpstamp | user_id |
|_______________|___________|______________________|__________|
| 1 | Hi | 2013-07-10 12:15:03 | 2 |
| 1 | Hello | 2013-07-09 12:14:44 | 1 |
|_______________|___________|______________________|__________|
this query is working fine and it uses just thw forum table:
SELECT forum.match_static_id,
count(forum.match_static_id) 'comments_no', max(forum.timestamp)'timestamp'
FROM forum
GROUP BY forum.match_static_id
Order BY timestamp DESC
But the following query is using two tables :
SELECT forum.match_static_id,
count(forum.match_static_id) 'comments_no', max(forum.timestamp)'timestamp', users.username
FROM forum
INNER JOIN users on users.id = forum.user_id
GROUP BY forum.match_static_id
Here I want to get the user of the max(timestamp) but i get the wrong user could any body give my a clue about this, please?
Order BY timestamp DESC
Try this:
SELECT f1.match_static_id,
f2.comments_no,
f2.maxtimestamp,
users.username
FROM forum AS f1
INNER JOIN
(
SELECT match_static_id,
max(timestamp) maxtimestamp,
count(comment) AS comments_no
FROM Forum
GROUP BY match_static_id
) AS f2 ON f1.match_static_id = f2.match_static_id
AND f1.timestamp = f2.maxtimestamp
INNER JOIN users on users.user_id = f1.user_id;
See it in action here:
SQL Fiddle Demo
I'm trying to combine 3 MySQL queries in to one.
This is what I am using to grab my news entries (with pagination) :
SELECT A.sid,
A.title,
A.time,
A.bodytext,
A.author,
A.url
FROM news A
INNER JOIN
(SELECT sid
FROM news
WHERE approved=1
ORDER BY sid DESC LIMIT $start, $limit) B USING (sid)
Now, I've recently added a comments feature and would like to get the total amount of comments for each "sid"
The part that gets confusing for me is that I need to match "sid" (from news.news) with "page_id" (from comments.pages) to grab it's unique "id".
+----+---------+
| id | page_id |
+----+---------+
| 1 | 87 |
| 2 | 86 |
| 41 | 85 |
| 3 | 84 |
| 13 | 83 |
+----+---------+
Now with that unique "id", I need to query "comments.comments" and match it with "page_id" column and count(*) how many comments it has - WHERE is_approved = 1
SELECT page_id,is_approved,count(*) FROM comments WHERE page_id = $id and is_approved = 1;
+---------+-------------+----------+
| page_id | is_approved | count(*) |
+---------+-------------+----------+
| 1 | 1 | 2 |
+---------+-------------+----------+
Is this possible?
Edited my response to conform to the updated question:
SELECT A.sid, A.title, A.time, A.bodytext, A.author, A.url,
D.page_id, D.num_comments
FROM news.news A
INNER JOIN (SELECT sid
FROM news
WHERE approved=1
ORDER BY sid desc
LIMIT $start, $limit) B USING (sid)
LEFT JOIN comments.pages C ON A.sid = C.id
LEFT JOIN (SELECT page_id,is_approved,count(*) as num_comments
FROM comments.comments
WHERE is_approved = 1) D ON C.page_id = D.page_id