Getting the average number from a meta value in wp - php

i've creating following wordpress query which output which is counting the records. However all posts does also have a meta_key with the name betting_odds where the meta_value is something like 2.05, 3.30
how can i add the average values of this meta_key into following query?
SELECT count(DISTINCT $wpdb->postmeta.`post_id`)
FROM $wpdb->posts
LEFT JOIN $wpdb->postmeta ON ($wpdb->posts.ID = $wpdb->postmeta.post_id)
LEFT JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id)
LEFT JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
WHERE $wpdb->postmeta.meta_key = 'betting_status'
AND $wpdb->postmeta.meta_value != 'Ikke afgjort'
AND $wpdb->posts.post_status = 'publish'
AND $wpdb->term_taxonomy.taxonomy = 'category'
AND $wpdb->term_taxonomy.term_id = 106

This is a common challenge when retrieving data from a key/value store like wp_postmeta.
The trick is to put both the post_id and the meta_key into the ON clause, like so.
(It's also helpful to use table aliases (in this case posts, stat, odds, etc.) in WordPress queries because they get quite a bit more readable.
SELECT count(DISTINCT posts.ID), AVG(odds.meta_value)
FROM $wpdb->posts posts
LEFT JOIN $wpdb->postmeta stat
ON posts.ID = stat.post_id
AND stat.meta_key = 'betting_status'
LEFT JOIN $wpdb->postmeta odds
ON posts.ID = odds.post_id
AND odds.meta_key = 'betting_odds'
LEFT JOIN $wpdb->term_relationships tr ON posts.ID = tr.object_id
LEFT JOIN $wpdb->term_taxonomy t ON tr.term_taxonomy_id = t.term_taxonomy_id
WHERE stat.meta_value != 'Ikke afgjort'
AND posts.post_status = 'publish'
AND t.taxonomy = 'category'
AND t.term_id = 106
Do you see how we are LEFT JOINing the postmeta table twice, once for each meta value we need?? Do you see how the meta_key match criterion goes into the ON clause, not the WHERE clause? That's the pattern to pull meta values for posts.

Related

How to inner join from another table and order by specific row value?

In WordPress, there are 2 tables: wp_terms and wp_termmeta.
I currently do the following to get the terms and parents etc:
$query = mysqli_query($mysqli, "
SELECT wp_terms.term_id,wp_terms.name, wp_term_taxonomy.parent
FROM wp_terms INNER JOIN wp_term_taxonomy ON wp_terms.term_id = wp_term_taxonomy.term_id
WHERE wp_term_taxonomy.taxonomy = 'post-categories'
ORDER BY name");
However - I need to access the wp_termmeta table, select a row where the term_id is the same and the meta_key is "order" then order by the meta_value of the wp_termmeta, instead of name as it is currently.
How would I do that with the current query?
I don't have wordpress-specific knowledge, but according to your description the query could look like this (I added table aliases for readability, but they are not necessary):
SELECT t.term_id, t.name, tax.parent
FROM wp_terms t
INNER JOIN wp_term_taxonomy tax ON t.term_id = tax.term_id
INNER JOIN wp_termmeta m ON m.term_id = t.term_id AND m.meta_key = 'order'
WHERE tax.taxonomy = 'post-categories'
ORDER BY m.meta_value
The most interesting part here is the join condition of the second join, which contains two conditions: m.term_id = t.term_id AND m.meta_key = 'order'
It first makes sure the term ids are matching and then assures that the meta key of the joined row is actually "order".

MySQL Wordpress Query: Select posts by meta value but also include category

Okay, trying to pull off some ninja development here, but getting a little stuck. I require the help of a true expert here. Thanks in advance.
This Query works excellent to return post information and category from outside of Wordpress:
SELECT wp_posts.ID,wp_posts.post_title,wp_terms.name as category FROM wp_posts
INNER JOIN wp_term_relationships ON wp_posts.ID = wp_term_relationships.object_id
INNER JOIN wp_term_taxonomy ON wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
INNER JOIN wp_terms ON wp_terms.term_id = wp_term_taxonomy.term_id
WHERE wp_term_taxonomy.taxonomy = 'category'
AND wp_posts.post_status = 'publish'
Now, this query works great for filtering by the company name, which is a meta field stored in the postmeta table. (The {$q} below is the sanitized company name)
SELECT ID,post_title,post_date,post_name,post_author FROM wp_posts,wp_postmeta
WHERE ID = wp_postmeta.post_id AND meta_key = 'company'
AND meta_value = \"{$q}\" AND wp_posts.post_status = 'publish'
ORDER BY post_date DESC
Anyway, both queries work great on their own. However, I want to combine them into one query so that I can select the category but still filter by company.
Any thoughts? I would love to hear your ideas on how to solve this problem. I'd give you 3x points for this answer if I could.
One way to accomplish this:
SELECT wp_posts.ID,wp_posts.post_title,wp_terms.name as vert FROM wp_posts
INNER JOIN wp_term_relationships on wp_posts.ID = wp_term_relationships.object_id
INNER JOIN wp_term_taxonomy on wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
INNER JOIN wp_terms ON wp_terms.term_id = wp_term_taxonomy.term_id
WHERE wp_term_taxonomy.taxonomy = 'category'
AND wp_posts.post_status = 'publish'
AND wp_posts.ID IN (SELECT post_id FROM wp_postmeta WHERE meta_key = 'company' AND meta_value = \"{$q}\" ) LIMIT 0,99999

Return the count of posts where meta value is equal to

I've created a custom field by using the Advanced Custom Fields plugin. This field is called status and by default is equal upcoming and then it will be changed to either correct or wrong later.
I'm then trying to query all the posts where the status meta value is equal to either correct or wrong. However even though i've set this in the below Query it still return the count of all posts. I've double checked and counted how many posts there are equal to correct or wrong and still i get the wrong count. What am i doing wrong?
SELECT count(DISTINCT posts.ID) as count, AVG(odds.meta_value) as ave
FROM $wpdb->posts posts
LEFT JOIN $wpdb->postmeta stat
ON posts.ID = stat.post_id
AND stat.meta_key = 'status'
LEFT JOIN $wpdb->postmeta odds
ON posts.ID = odds.post_id
AND odds.meta_key = 'odds'
LEFT JOIN $wpdb->term_relationships tr ON posts.ID = tr.object_id
LEFT JOIN $wpdb->term_taxonomy t ON tr.term_taxonomy_id = t.term_taxonomy_id
WHERE stat.meta_value = 'wrong'
OR stat.meta_value = 'correct'
AND posts.post_status = 'publish'
AND t.taxonomy = 'category'
AND t.term_id = 4
OR t.term_id = 5
OR t.term_id = 6
You should use brackets to group together what should be together:
SELECT count(DISTINCT posts.ID) as count, AVG(odds.meta_value) as ave
FROM $wpdb->posts posts
LEFT JOIN $wpdb->postmeta stat
ON posts.ID = stat.post_id
AND stat.meta_key = 'status'
LEFT JOIN $wpdb->postmeta odds
ON posts.ID = odds.post_id
AND odds.meta_key = 'odds'
LEFT JOIN $wpdb->term_relationships tr
ON posts.ID = tr.object_id
LEFT JOIN $wpdb->term_taxonomy t
ON tr.term_taxonomy_id = t.term_taxonomy_id
WHERE (stat.meta_value = 'wrong'
OR stat.meta_value = 'correct')
AND posts.post_status = 'publish'
AND t.taxonomy = 'category'
AND (t.term_id = 4
OR t.term_id = 5
OR t.term_id = 6)

WordPress Query get posts based on custom table

I have some regular WordPress posts that I need to get from the database by parent category, and order by the results of a custom table in the database that I have made.
The parent category that I want to retrieve posts for (including children) is called explorer with the id of 29.
The custom table is called wp_upvotes. in this table there are a few columns, but the only columns that we care about would probably be id and postID. I want to order the wp_posts by the number of rows that has the postID equal to the wp_post.ID, and if there are no rows in that table for the other posts, then they should be ordered by date at the end. I want the most number of upvotes to the least number of upvotes by date.
The query I have tried is this (it returns only the first post, not all of them):
$catIDs = array(29,30,31,32);
SELECT wp_posts.*, COUNT(wp_upvotes.id) AS upvotes FROM wp_posts
LEFT JOIN wp_upvotes ON (wp_posts.ID = wp_upvotes.postID)
INNER JOIN wp_term_relationships
ON (wp_posts.ID = wp_term_relationships.object_id)
INNER JOIN wp_term_taxonomy
ON (wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
AND wp_term_taxonomy.taxonomy = 'category'
AND wp_term_taxonomy.term_id IN (" . implode(',', $catIDs) . "))
AND wp_posts.post_status = 'publish'
ORDER BY upvotes DESC, wp_posts.post_date DESC
When I remove the LEFT JOIN for the wp_upvotes table it returns all of the correct posts.. Why is it only returning one row when I am using a LEFT JOIN?
SELECT wp_posts.* FROM wp_posts
INNER JOIN wp_term_relationships
ON (wp_posts.ID = wp_term_relationships.object_id)
INNER JOIN wp_term_taxonomy
ON (wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
AND wp_term_taxonomy.taxonomy = 'category'
AND wp_term_taxonomy.term_id IN (" . implode(',', $catIDs) . "))
AND wp_posts.post_status = 'publish'
ORDER BY wp_posts.post_date DESC
Looks like the main factor was to use ORDER BY wp_posts.ID for whatever reason to make it show all of the rows instead of just one.. Odd but here's my final code to do what I wanted to do above:
SELECT wp_posts.*, COUNT(wp_upvotes.id) AS upvotes FROM wp_posts
INNER JOIN wp_term_relationships
ON (wp_posts.ID = wp_term_relationships.object_id)
INNER JOIN wp_term_taxonomy
ON (wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
AND wp_term_taxonomy.taxonomy = 'category'
AND wp_term_taxonomy.parent = 29)
LEFT JOIN wp_upvotes ON (wp_posts.ID = wp_upvotes.postID)
WHERE wp_posts.post_status = 'publish'
GROUP BY wp_posts.ID
ORDER BY upvotes DESC, wp_posts.post_date DESC

sql statement for querying wp posts from specific category

i want to query wordpress posts from specific category parent but the problem is that there is no such column on wp_posts table so i need to join but my skills on the sql is not good so i need some help ,
here is the query i use for querying posts
$query = "SELECT c.*
FROM {$wpdb->prefix}posts p,
{$wpdb->prefix}comments c WHERE p.ID = c.comment_post_ID AND c.comment_approved > 0 AND p.post_type = 'product' AND p.post_status = 'publish' AND
p.comment_count > 0 ORDER BY ".$order_by." LIMIT 0, ". $number_of_comments;
}
and here is some snippet i found for joining term_taxonomy_id
$answer = $wpdb->get_results("SELECT post_title, post_content, term_taxonomy_id FROM wp_posts LEFT JOIN wp_term_relationships ON wp_posts.ID = wp_term_relationships.object_id WHERE SUBSTRING(post_title,1,1)='T' AND term_taxonomy_id=6");
the proplem i can't seem to figure how to use this example on my query neither thinking of simpler solutions so i can query from specific parent category , thanks for your help
here is the query i used and worked ..
$query = "SELECT c.*
FROM
{$wpdb->prefix}comments c ,
{$wpdb->prefix}posts p JOIN $wpdb->term_relationships TR
ON p.ID=TR.object_id
JOIN $wpdb->term_taxonomy T
ON TR.term_taxonomy_id=T.term_taxonomy_id
JOIN $wpdb->terms TS
ON T.term_id = TS.term_id
WHERE p.ID = c.comment_post_ID AND c.comment_approved > 0 AND p.post_type = 'product' AND p.post_status = 'publish' AND
p.comment_count > 0 AND T.taxonomy = 'product_cat' AND T.term_id='$term_cat' ORDER BY ".$order_by." LIMIT 0, ". $number_of_comments;
}
you would be looking at something like this:
global $wpdb;
$wpdb->show_errors();
$ur=$wpdb->get_results( $wpdb->prepare(
"
SELECT *
FROM $wpdb->posts P
JOIN $wpdb->term_relationships TR
ON P.ID=TR.object_id // identify link column
JOIN $wpdb->term_taxonomy T
ON TR.term_taxonomy_id=T.term_taxonomy_id
JOIN $wpdb->terms TS
ON T.term_id = TS.term_id
WHERE P.post_type = %d // use wild chars (define below, this one equals carmarket)
AND P.post_status = %f
AND T.taxonomy= %s
",
'carmarket',
'publish',
'carmake'
) );
$wpdb->print_error();
var_dump($ur);

Categories