Using a simple JOIN - php

I have a posts table with id column and more, and a votes table with post_id, value columns and more. Each post_id can be repeated in the votes table.
Now I want to select the most voted posts (and the number of votes) from the database, and I've tried the next:
$query = "SELECT p, SUM(v.value) FROM {$wpdb->posts} p, wp_wti_like_post v JOIN p.id v.post_id WHERE 1=1";
$myrows = $wpdb->get_results( $query );
var_dump($myrows);
but it retrieves an empty array.
Note: {$wpdb->posts} is the correct table for the posts

You need to group by post.id to get a proper sum per post. Then you can sort descending by that sum and get the first row (= highest value).
SELECT
p.*, /* Not sure if this will work. Maybe you have to
specify exact fields you need, although MySQL
is pretty forgiving. */
SUM(v.value) AS number_of_votes
FROM
{$wpdb->posts} p
INNER JOIN wp_wti_like_post v ON v.post_id = p.id
GROUP BY
p.id
ORDER BY
SUM(v.value) DESC
LIMIT 1";

I haven't tested that, but it should work for you.
SELECT {$wpdb->posts}.*,wp_wti_like_post.*, SUM(wp_wti_like_post.value) as Svalue
FROM {$wpdb->posts}
JOIN wp_wti_like_post ON wp_wti_like_post.post_id = {$wpdb->posts}.id

Related

left join alle topics only last post order by sticky and last post DESC

i am trying to get all topics based on a forum ID.
Those topics need to be ordered by sticky first and then by last post date secondly.
I have this query, working almost fine but it doesn't order the topics in the way i want.
SELECT
forum_posts.posted_by,
forum_posts.posted,
forum_topics.id,
forum_topics.subject,
forum_topics.sticky,
forum_topics.closed
FROM
forum_posts
LEFT JOIN
forum_topics
ON
forum_topics.id=forum_posts.topic_id
WHERE forum_topics.forum_id=$forumdata->id
GROUP BY forum_topics.id
ORDER BY forum_posts.posted DESC
If I read your question correctly, then you only need to make a slight change to the ORDER BY clause:
ORDER BY
forum_topics.sticky, -- just add this
forum_posts.posted DESC;
However, as you are selecting non aggregate columns, my hunch is that you should really be using a subquery to figure out the latest post:
SELECT
ft.*, fp1.*
FROM forum_posts fp1
INNER JOIN
(
SELECT topic_id, MAX(posted) AS max_posted
FROM forum_posts
GROUP BY topic_id
) fp2
ON fp1.topic_id = fp2.topic_id AND
fp1.posted = fp2.max_posted
LEFT JOIN forum_topics ft
ON fp1.id = ft.topic_id
ORDER BY
ft.sticky;
if you need sticky first an then post then you need order by orum_topics.sticky, forum_posts.posted eg:
SELECT
forum_posts.posted_by,
forum_posts.posted,
forum_topics.id,
forum_topics.subject,
forum_topics.sticky,
forum_topics.closed
FROM
forum_posts
LEFT JOIN
forum_topics
ON
forum_topics.id=forum_posts.topic_id
WHERE forum_topics.forum_id=$forumdata->id
GROUP BY forum_topics.id
ORDER BY forum_topics.sticky DESC, forum_posts.posted DESC

SQL query with count and group by in three tables

I am working on an sql query where I have three tables posts, users and comments. I want to display all posts with its users and number of comments on this. I have following query but it is giving me wrong result:
SELECT
c.userid, count(c.userid), p.postid
FROM comments c, posts p
where c.userid = p.userid group by c.userid
In addition to above query I also require firstname and lastname from users table.
Try something like this,
SELECT
u.userid, u.firstname, u.lastname,p.post, p.postid,
count(c.userid) totalcoments -- may be c.commentid
FROM users u
JOIN posts p ON p.userid=u.userid
LEFT JOIN comments c OM c.postid=p.postid
GROUP BY u.userid, u.firstname, u.lastname,p.post, p.postid
Try something like the following:
SELECT
postid
, p.userid
, COALESCE((
SELECT COUNT( * ) FROM comments WHERE postid = p.id
), 0 ) AS cnt_postid
, COALESCE( ( SELECT CONCAT( firstname, ' ', lastname ) FROM users WHERE userid = p.userid ), 'N/A' ) AS NAME
FROM posts p
LEFT JOIN comments c ON c.postid = p.id
GROUP BY postid
ORDER BY postid
you are probably getting the same amount of count because you not using a group by.
GROUP BY must always be used when using aggregate function. What the group by does is that it will select all unique posts and the the count will return the number of users for that one unique post

SQL query with special conditions not working

please help me with my MySQL Query.
Basically I want to retrieve some users for a user-ranking-system. My project is based on a wordpress installation. But since my query is very specific, all wordpress methods and functions are useless.
I try to describe my query in words:
"Give me all Users, who have a minimum of three posts which have a minumum rating of 4 for each post. Furthermore each of the users post needs to have a minimum of 5 ratings."
(The date-conditions below in the query are unimportant, work perfectly)
For storing data, posts are saved as usual in wp_posts (special post_type). The amount of ratings for each post is stored with a meta value (key=rating_count). Each rating is stored in the table "wp_rating" (id, post_id, rating, user_id).
My Query looks like this:
SELECT SUM(r.rating) AS rating,
p.post_author AS user_id,
COUNT(r.rating) AS rating_count
FROM wp_rating r
INNER JOIN wp_posts p ON p.ID = r.post_id
INNER JOIN wp_postmeta meta ON meta.post_id = p.ID
WHERE p.post_status = 'publish'
AND (meta.meta_key = 'expiration_date'
AND meta.meta_value < DATE_FORMAT(NOW(), 'Ymd'))
AND (meta.meta_key = 'rating_count' AND meta.meta_value > 4)
AND MONTH(p.post_date) = 03
AND r.rating > 4
GROUP BY p.post_author
HAVING COUNT(p.ID) > 3
ORDER BY SUM(r.rating) DESC
The problem is the following line:
AND (meta.meta_key = 'rating_count' AND meta.meta_value > 4)
I dont get any results after firing this query. (I checked all posts twice for enough ratings)
I hope my description is okay for finding a solution.
Kind Regards,
Robin :-)
PS: Please help, Im very confused :(
At the same time column can be equal to one value meta.meta_key = 'expiration_date' or meta.meta_key = 'rating_count' how it is possible that at same time column can have these two values, i guess you have one to many relation between post and their meta you need another join to your wp_postmeta table to fullfill your second condition,and make sure you are comparing date to date type here meta.meta_value it smells like you have text type of meta.meta_value column
SELECT SUM(r.rating) AS rating,
p.post_author AS user_id,
COUNT(r.rating) AS rating_count
FROM wp_rating r
INNER JOIN wp_posts p ON p.ID = r.post_id
INNER JOIN wp_postmeta meta ON meta.post_id = p.ID
INNER JOIN wp_postmeta meta1 ON meta1.post_id = p.ID
WHERE p.post_status = 'publish'
AND (meta.meta_key = 'expiration_date'
AND meta.meta_value < DATE_FORMAT(NOW(), 'Ymd'))
AND (meta1.meta_key = 'rating_count' AND meta1.meta_value > 4)
AND MONTH(p.post_date) = 03
AND r.rating > 4
GROUP BY p.post_author
HAVING COUNT(p.ID) > 3
ORDER BY SUM(r.rating) DESC
i guess 'rating_count' you mean it the aliace you created before.
try that:
AND (meta.meta_key = COUNT(r.rating) AND meta.meta_value > 4)

how to order data in mysql by join count?

I have two tables :
posts : id,title,content,show,created_at
comments: id,post_id,created_at
I'm trying to order posts by most commented.
SELECT *, COUNT(comments.id) AS total_comments
FROM comments LEFT JOIN posts ON posts.id = comments.post_id
WHERE posts.show = '1'
GROUP BY complains.id
ORDER BY total_comments DESC
The problem is that the posts with 0 comments don't appear.
Any help would be much appreciated.
With your join above, you are incorrectly joining to get commens that have posts
You should have done a right join or swap the tables in left join like below.
Select *, COUNT(comments.id) as total_comments
FROM posts
LEFT outer JOIN comments on posts.id = comments.post_id
WHERE posts.show = '1'
GROUP BY posts.id
ORDER BY total_comments DESC
You need to do a RIGHT JOIN instead of a LEFT JOIN. Or swap the tables in the LEFT JOIN clause.
While there are many ways to solve this, I think this code is easy to read and understand.
The query in the LEFT JOIN can be copied out and run on its own to help debug. Then you join that result set to the posts table and order the results.
SELECT p.*, IFNULL(c.total_comments, 0) as total_comments
FROM posts p
LEFT JOIN (select post_id, count(post_id) as total_comments from comments group by post_id) as c ON p.id = c.post_id
WHERE p.show = '1'
ORDER BY c.total_comments DESC

php query with 2 counts and joins

im running a query that usses 3 tabels "post, likes and comment" i need to get the ammount of likes and comments the post has got, and at the same time get the basic info from the post table so im using the query bellow but the problem is that it copys the value likeAmount to commentAmount if likes is bigger unless comments is 0.
SELECT post.*, COUNT(likes.id) as 'LikeAmount', COUNT(comment.id) as 'commentAmount' FROM post
LEFT JOIN likes ON post.id = likes.post
LEFT JOIN comment ON post.id = comment.post
GROUP BY post.id
ORDER BY LikeAmount DESC"
so that doesnt work but when i add distinct it does work, so when its like this:.
SELECT post.*, COUNT(distinct likes.id) as 'LikeAmount', COUNT(distinct comment.id) as 'commentAmount' FROM post
LEFT JOIN likes ON post.id = likes.post
LEFT JOIN comment ON post.id = comment.post
GROUP BY post.id
ORDER BY LikeAmount DESC";
i dont see why it works with distinct and doesnt with out, and does distinct mather performance wise or does it make no diffrence sinds it will be used in a website that has a lott of trafic..
try this, not short, but readable:
SELECT
p.*,
pl.like_count,
pc.comment_count
FROM post p
#join likes
LEFT OUTER JOIN (
SELECT
post,
COUNT(*) AS like_count
FROM likes
GROUP BY post
) AS pl
ON pl.post = p.id
#join comments
LEFT OUTER JOIN (
SELECT
post,
COUNT(*) AS comment_count
FROM comment
GROUP BY post
) AS pc
ON pc.post = p.id
Perhaps using SUM instead of COUNT to handle the records where there is no join would work, and should perform just as fast:
SELECT post.id,
SUM(IF(likes.id IS NULL,0,1)) as 'LikeAmount',
SUM(IF(comment.id IS NULL,0,1)) as 'commentAmount'
FROM post
LEFT JOIN likes ON post.id = likes.post
LEFT JOIN comment ON post.id = comment.post
GROUP BY post.id
ORDER BY LikeAmount DESC"

Categories