In phpbb3 I want to select latest 10 active topics. i.e topics that lastly has posts. In the PHPbb3 schema, the table topics has many posts. In order to achieve this, I tried the following SQL
SELECT DISTINCT (`t_topics`.`topic_id`), `t_topics`.topic_title FROM
`t_topics` , `t_posts` WHERE `t_posts`.topic_id = `t_topics`.topic_id
ORDER BY `t_posts`.post_id DESC LIMIT 10;
However, there is a topic that I'm sure that it has the latest post and it comes at the end of records.
I tried to remove DISTINCT However, I got have the correct order, but there are repeated topics. I want to get the correct order with no repeated topics but I don't know how?
You can use group by clause instead of Distinct on t_topics.topic_id.
Query is : SELECT t_topics.topic_id, t_topics.topic_title FROM t_topics , t_posts WHERE t_posts.topic_id = t_topics.topic_id GROUP BY t_topics.topic_id ORDER BY t_posts.post_id DESC LIMIT 10;
Related
I'm creating a message board. When a topic gets a reply, the entire topic (all rows that has the topicid) must be bumped to the top of the forum. Pinned topics should always be displayed first, then followed by the topic that has the most recent post date because they are bumped to the top when they get a reply.
This is a pic of the table that contains the posts.
DB Table before query
I need 1 query that will do the following:
group all the topicid together (lets call this "group");
within each group sort the rows by parentid ascending, but NULL always is sorted first;
groups that are "pinned" are displayed first
then groups that have the "latest" post displayed first
The query should give the following results
Results of the query
I think this query will do what you want.
SELECT *
FROM messages m
ORDER BY IF(pinned='yes','9999-12-31 23:59:59', (SELECT MAX(date) FROM messages m2 WHERE m2.topicid = m.topicid)) DESC,
topicid, IFNULL(parentid, 0)
The first part of the order by ensures that groups that are pinned are ordered first, followed by groups that have the most recent post. It does this by selecting the maximum possible date when the group is pinned, otherwise the latest date for posts in that group and sorts by that value descending. The second part then sorts those posts by topicid, and the final part sorts by parentid. To ensure that posts with a NULL parentid sort first, we use an IFNULL clause on parentid to set the sorting value to 0 when parentid is NULL.
I've created an SQLFiddle to demonstrate this.
Edit This updated query will also sort pinned topics by latest date instead of just by topicid. It does this by adding 1000 years to the date of pinned posts, thus ensuring that pinned posts sort ahead of non-pinned posts while retaining the ordering between pinned posts as well.
SELECT *
FROM messages m
ORDER BY (SELECT MAX(IF(pinned='yes', date + interval 1000 year, date))
FROM messages m2
WHERE m2.topicid = m.topicid) DESC,
topicid, ifnull(parentid, 0)
Here's an updated SQLFiddle to demonstrate.
I'm afraid I can only answer parts of your question, but I'm giving it a shot and posting it anyway in the hope that it will help you solve your issue.
First, I'd grab the pinned messages (lastest first in this query):
SELECT * FROM messages WHERE pinned = 1 ORDER BY date DESC
Then, you can grab - let's say - the 10 most recent topics:
SELECT MAX(date) AS latest, topicid FROM messages GROUP BY topicid ORDER BY latest DESC LIMIT 10
Now you should know the topicids from which you want to display messages. You could "chain together" the messages with a join:
SELECT * FROM messages AS m1 JOIN messages AS m2 ON m1.postid = m2.parentid WHERE m1.topicid IN <some stuff here> ORDER BY m1.topicid ASC, m1.postid DESC
Sorry for the incomplete answer. Any comments to help me fill the gaps are welcome ;)
I tried to search everywhere, but not found any answer.
I have two different tables in database with only two same columns (name, dateChanged) and really many others which are different in both tables. I wish to get latest X updates from both tables (in future from more tables) but I cannot find the way to do it. I mean something like
SELECT `name`, `dateChanged` FROM `mpolymer`, `mmetal` ORDER BY `dateChanged` DESC LIMIT 0,10
to show quick summary of newest activities. I tried UNION, JOIN, but all of these need to join on some common column, which is not possible (I think). Do you have any possibilities to do what I wish to do, please?
Assuming that you want the last X events across both tables (not X events from one and X events from the other), this should work for you.
SELECT name, dateChanged FROM mpolymer
UNION
SELECT name, dateChanged FROM mmetal
ORDER BY dateChanged DESC limit 10;
DEMO
To also show the table name (based on your comment)…
SELECT name, dateChanged, 'mpolymer' AS tableName FROM mpolymer
UNION
SELECT name, dateChanged, 'mmetal' AS tableName FROM mmetal
ORDER BY dateChanged DESC limit 10;
DEMO
I have the following table that stores messages between users:
I need to display a list of all last message for a users (from all users that have had contact with).
You will see to users being 1000000002 & 1000000172 for example. I need to show the last message between them which could be rows 1 to 4 - but would be 4 as last time.
I have tried the query below but its still isn't right:
SELECT sender_userid,receiver_userid,message,message_read,`datetime` FROM messages
WHERE (receiver_userid='1000000172' OR sender_userid='1000000172') AND friendship_status=1 AND receiver_history=1
GROUP BY receiver_userid
ORDER BY `datetime` ASC;
I find the order by doesn't get the most resent - could be because its after the Group By.
Also find it treats the sender_userid & receiver_userid as different rows in the Group By. I'm unsure how to get the most resent out of both.
thankyou so very much
Your GROUP BY should throw you errors, but MySQL just gives you garbage instead :)
You do not even need a group by, you simply want a list of all messages in which user X is involved and you want to sort them, so you have most of the work domn allready:
SELECT *
FROM messages
WHERE (receiver_userid='1000000172' OR sender_userid='1000000172')
AND friendship_status=1 AND receiver_history=1
ORDER BY `datetime` DESC;
Mind that you want to sort descending if you want the most recent ones first!
use DESC instead of ASC. DESC means large one is first.
I've designed a simple website which enables users to search on a MYSQL database. The search method is also simple: the user types a word in a textfield and it searches in the database.
Now i want to include in this website a table with the most searched words and i didn't find anything until now but this sentence:
select distinct column
, count(1) as total
from dept
group by column
order by total desc
limit 5
but this doesnt retrieve what i want. Do you have any idea of how I get this result?
Thank you in advance!
A simple example for a small site:
After each search, add a row to a table searched. Bonus points for adding a timestamp.
insert into searched (keyword, timestamp) values ('foo', 1234567890);
From there:
select keyword, count(*) as total from searched
group by keyword order by total desc limit 5;
Of course, for simple things like this, I'd use redis.
I am currently building a simple PHP + MySQL forum but I am having problems with getting the information to show in the correct format.
My current SQL code is
SELECT forum_posts.catId, forum_posts.postId, forum_posts.date, forum_posts.message,
forum_posts.userId, users.userId, users.username, forum_thread.threadId, forum_thread.subjectTitle
FROM forum_posts
LEFT JOIN forum_thread ON forum_posts.threadId = forum_thread.threadId
LEFT JOIN users ON users.userId = forum_posts.userId
GROUP BY forum_posts.catId
ORDER BY forum_posts.postId DESC, forum_posts.date DESC, forum_posts.catId ASC
The problem I have is that it brings back everything in the right category but it brings back the first result of the category and not the last one.
I simply want the code to show the last reply in each category.
Any help is much appreciated thank you.
Your query should return a range of rows. Try to limit the result to 1 element. If you sort the results descending, you will get the last item.
ORDER BY ... DESC LIMIT 1
I am not sure whether you find the latest entry by postId or date. If you find it by date, you must start the grouping with the date.
But I don't understand why you are sorting the results so much for getting only one dataset.
ORDER BY forum_posts.date DESC LIMIT 1;
Is this what you want? Additionally this could help you: Select last row in MySQL.