Ordering By Another Table Column If Exists - php

I'm putting together a simple forum script with topics/posts. I'm trying to order topics by latest post and I've had some luck with the answer in the following question: MYSQL Order from another Table, but the problem I have is that some topics don't have any posts yet, so the query doesn't select those topics at all.
Current coding is:
SELECT DISTINCT forum.*
FROM forum
INNER JOIN forum_posts
ON forum.id = forum_posts.parent_id
GROUP BY forum.id
ORDER BY forum_posts.parent_id DESC,
forum_posts.time_created DESC
LIMIT ?,?
I want to tell the ORDER BY to order by forum.time_created if there are no matches in forum_posts.parent_id for a topic.
On a side note, I would also like to know how to put a WHERE clause into this query as well. I want to only get rows from forum table "WHERE access <= ?", but can't work out where to put that snippet in.
Any help much appreciated!
EDIT:
Target is to return topics (from forum table)
According to following details:
WHERE forum.access <= ?
LIMIT ?,?
ORDER BY
Latest Post From forum_posts table with forum_posts.parent_id matching on forum.id,
or forum.time_created
EDIT 2:
An example SQLfiddle with relevant data. This doesn't work as the order should really come out as 11,10,9,1,2
http://sqlfiddle.com/#!2/83535/2

Have a look at this: http://sqlfiddle.com/#!2/be909/1
Here's my final query:
SELECT forum.*, recent_forum_posts.time_created as latest_post
FROM forum
LEFT JOIN (SELECT MAX(forum_posts.time_created) as time_created, forum_posts.parent_id
FROM forum_posts
GROUP BY forum_posts.parent_id) AS recent_forum_posts
ON forum.id = recent_forum_posts.parent_id
WHERE forum.access > 2
ORDER BY recent_forum_posts.time_created IS NULL DESC,
recent_forum_posts.time_created DESC,
forum.time_created DESC
LIMIT 5
Essentially, the subquery (the bit in brackets after LEFT JOIN) selects the most recent post for each parent_id from the forum_posts table.
That is then LEFT JOINed (as we want to list all forum's even if there are no posts yet).

Related

Getting two different results by one SQL query

First I am new to SQL and PHP.
I have created a simple social networking web app so users can post and follow others to see new posts from them.
At home page a user can first see posts from all users he is followong.
but what i want is to make the user see some other random popular posts that will be ordered by Likes.
here what i have done to get posts from users i follow:
SELECT * FROM posts WHERE author_id in
(SELECT followedID FROM follows WHERE
followerID=:myID)
ORDER BY id DESC LIMIT 10
Now let's say you are following only 1 person. and that person has only one post. here you will see no more than a post!
That's why i want to show more posts when a user has already seen all posts.
i want some easy way to get other posts when the above query has done getting some specific posts.
This is the next query i'd like to execute.
SELECT * FROM posts ORDER BY post_likes DESC LIMIT 10
I wouldn't recommend union, because it incurs overhead for removing duplicates.
Instead, you can use a LEFT JOIN:
SELECT p.*
FROM posts p LEFT JOIN
follows f
ON p.author_id = f.follows_id AND
f.followerID = :myID
ORDER BY (f.follows_id IS NOT NULL) DESC,
(CASE WHEN f.follows_id IS NOT NULL THEN p.id END),
p.post_likes DESC
LIMIT 10;
The ORDER BY puts the followed posts first. The other two clauses order each of the groups by the criteria you want.
You may use UNION to do what you want
(SELECT * FROM posts WHERE author_id in
(SELECT followedID FROM follows WHERE
followerID=:myID)
ORDER BY id DESC limit 0,10)
union
(SELECT * FROM posts ORDER BY post_likes DESC limit 0,10)
LIMIT 0, 10
UNION will automatically append the 2nd query result to the 1st query result, and then show only the number of records specified by the LIMIT clause
Please note that union works only if the queries are of the same structure (which in this case is positive)
Please note that the use of parenthesis is mandatory if you use order by or limit or both
I have used 3 limit clauses (one for each query , and one for the final result of union) AND Both queries have ORDER BY clause. This is to make sure that the records extracted are what you want. (to show the followed posts first, and both are ordered properly)

How to get the most commented articles using SQL?

We have 2 tables: articles, comments.
The structure of this tables:
articles(article_id(PK), etc);
comments(comment_id(PK), article_id(FK)).
I need to get a list of the most commented articles.
I used the request:
SELECT articles.article_id, COUNT(comments.article_id)
FROM comments
INNER JOIN articles ON comments.article_id = articles.article_id AND comments.article_id = :article_id.
What should be the request to get an array of data with 3 most commented articles?
Is it really possible to do this with SQL?
You should be able to get what you want with this query:
SELECT articles.article_id, COUNT(comments.article_id) AS num_comments
FROM comments
INNER JOIN articles ON comments.article_id = articles.article_id
GROUP BY articles.article_id
ORDER BY num_comments DESC
LIMIT 3
If you just need the article id, then a join is not necessary:
SELECT c.article_id, COUNT(*) AS num_comments
FROM comments c
GROUP BY c.article_id
ORDER BY num_comments DESC
LIMIT 3
The query below will provide to you a list of articles and the number of comments for each of these articles ordering them in descending order of number_of_comments
SELECT articles.article_id, COUNT(comments.article_id) AS comment_count
FROM articles, comments
WHERE articles.article_id=comments.article_id
GROUP BY articles.article_id
ORDER BY comment_count DESC
there is an easier way, you can add 'n-comments' column on the article table and initialize it to zero, and with your function to submit a comment, update the value of the 'n-comments++' after every comment.
thin every article will contain the number of its comments, and it will be very easy to select the most commented articles by:
"SELECT article_id FROM articles ORDER BY n-comments DESC LIMIT 50"
I think it will be easier and faster, hope it can help

Select over multiple tables. Wordpress

I'm trying to figure out how to do this on my own but it looks like a dead end to me.
I am working under wordpress framework and with some custom tables.
The result i am trying to achieve is very simple but the way to get there is just too much for my head right now.
I need to select the top 50 results from tableOne based on the ammount of times that the id from tableOne is mentioned in tableTwo under some simple where conditions.
Using $wpdb class for the latest WordPress build, what can i use to achieve this?
Thanks
This is the Simple tableOne Query to get all posts:
$allPosts = $wpdb->get_results("SELECT * FROM pokeGrid_images WHERE status='0' ORDER BY tempo DESC LIMIT ".$limit." OFFSET ".$offset."");
Now i need the first 50 results from this table, based on the number of times their id is mentioned on the second table with this structure: http://prntscr.com/byz2qw
Edit:
http://prntscr.com/byz79b
Note: Basically this is a forum, table one has the posts, table 2 the upvotes.
The expression must gather the most upvoted posts for the last X days.
If it was 1 post the expression would be Select Count(*) FROM tableTwo Where tempo > then ".$variableWithUnixTimeDIff."
column tempo is a now() timestamp.
Thanks
Note: Basically this is a forum, table one has the posts, table 2 the
upvotes. The expression must gather the most upvoted posts for the
last X days. If it was 1 post the expression would be Select Count(*)
FROM tableTwo Where tempo > then ".$variableWithUnixTimeDIff."
SELECT *, Sum(score) AS totalScore FROM tableTwo INNER JOIN tableOne ON tableTwo.memeID = tableOne.id GROUP BY memeID ORDER BY totalScore DESC;
Try this query.
//Edit - I just created a sample table with my own data. I only created the tableTwo, where this query did work:
SELECT *, Sum(score) AS totalScore FROM tableTwo GROUP BY memeID ORDER BY totalScore DESC
So after that, just inner join data from tableOne and it will work!

sql - select data from 2 tables

I have 2 tables - chats_topices and chats_replies
I would like to select all chats_topices fields + the field createDate (timestamp) from chats_replies which closest to the current date.
chats_replies contain field CHATID that connect between the tables
$sql = "SELECT *
FROM `chats_topics` AS topics, `chats_replies` AS replies
WHERE (".$search.") AND
(topics.id = replies.chatID) AND
(XXXX)
ORDER BY topics.createDate DESC";
It's bad practice to use SELECT * in live code, I'd go with something like this;
SELECT topics.Field1, topics.Field2, MAX(replies.createDate) createDate
FROM `chats_topics` AS topics
LEFT JOIN `chats_replies` AS replies
ON topics.id = replies.chatID
WHERE (".$search.")
AND (topics.id = replies.chatID)
AND (XXXX)
GROUP BY topics.Field1, topics.Field2
ORDER BY topics.createDate DESC
Add in your fields that you need to the select and also add them in the group by.
Rich Benner gave you a good join statement for this particular problem. I would like to follow up and attach an image I have found useful when making join statements in the hopes that it might help in the future. I don't remember where I got this picture (although you can see a copyright on the bottom).

Sorting a MySQL query based on another query?

I'm building some very simple forum software as a sort of self-test for my PHP and MySQL skills, but I'm not quite sure how to accomplish this task. I have a table called Threads which contains a list of all threads. I also have a table called Posts, which contains all posts. Each table's primary key is an auto-increment ID. Each row in Posts also contains the ID of the thread it belongs to.
While I can easily retrieve all of the threads in a certain subforum with a query like this:
SELECT * FROM Threads WHERE ForumID='$forumid'
...I'm not sure how to sort that based on the latest post from each thread. I can get the posts for any given thread like this:
SELECT * FROM Posts WHERE ThreadID='$threadid'
...but I don't know how to incorporate that data into my initial query to sort it. Since each post has a unique ID, posts with higher IDs will always be more recent, so there's no need to compare dates or anything like that. I'm just unclear on how to actually do the query.
I'm pretty sure that this is possible in just MySQL, but if it's not, what would be the most efficient PHP solution? Thanks!
Try this with INNER JOIN
SELECT p.*,t.*
FROM Threads t
INNER JOIN Posts p ON t.id = p.ThreadID
ORDER BY
//whatever column you want like this p.date
p.date
DESC
Thomething like this can helps you
SELECT DISTINCT t.* FROM Posts p LEFT JOIN Threads t ON p.ThreadID = t.id ORDER BY p.last_modified_time DESC
Or
SELECT DISTINCT t.* FROM Posts p LEFT JOIN Threads t ON p.ThreadID = t.id ORDER BY p.id DESC
A simple JOIN statement is the solution:
SELECT *
FROM Threads t
JOIN Posts p ON t.ThreadID = p.ThreadID
ORDER BY t.ModificationDate DESC -- or whatever column you want
This gives you the latest posts over all threads.
All of the given answers were very close, but I ended up using the following query:
SELECT t.*
FROM Threads t
INNER JOIN Posts p ON t.id = p.threadId
GROUP BY t.id
ORDER BY MAX(p.id) DESC
This is due to DUPLICATE causing problems due to its auto-grouping. See this answer for more info on the topic.

Categories