I am working on a custom plugin in wordpress. I have a weird issue with one sql.
SQL:
SELECT SQL_CALC_FOUND_ROWS 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 )
WHERE 1 =1
AND wp_term_taxonomy.taxonomy = 'category'
AND wp_term_taxonomy.term_id IN ('23')
AND (
wp_posts.post_author =1
)
AND wp_posts.post_type = 'post'
AND (
wp_posts.post_status = 'publish'
OR wp_posts.post_status = 'private'
)
GROUP BY wp_posts.ID
ORDER BY `wp_posts`.`as_stats_rating` DESC
LIMIT 0 , 30
Its returning the correct data but its not sorting results according to as_stats_rating.
I am stumped. Does anyone know what I am doing wrong?
Edit 1 : Update
Here is the structure of wp_posts:
Sample result:
ID as_stats_rating
1221 8
1222 10
All fields in sample results are :
ID post_author post_date post_date_gmt post_content post_title post_excerpt post_status comment_status ping_status post_password post_name to_ping pinged post_modified post_modified_gmt post_content_filtered post_parent guid menu_order post_type post_mime_type comment_count as_stats_numviews as_stats_numvotes as_stats_votestotal as_stats_rating
By the way, its not only about 'order by wp_posts.as_stats_rating', 'order by wp_posts.as_stats_numviews' have the same issue. (just to clear up, if you are wondering about as_stats_rating having varchar type)
Any chance that the as_stats_rating field is a string (char/text) datatype and not a numeric (float/int/decimal) datatype?
Related
here is my custom sql query ;
SELECT id,
post_title,
post_content,
comment_count,
post_date,
post_status,
post_name
FROM wp_posts
WHERE post_type = 'post'
AND post_status = 'publish'
AND id NOT IN (SELECT DISTINCT post_id
FROM wp_postmeta
WHERE meta_key = 'visible_headlane'
AND meta_value = 'On')
AND id NOT IN (SELECT DISTINCT post_id
FROM wp_postmeta
WHERE meta_key = 'visible_homepage'
AND meta_value = 'On')
ORDER BY post_date DESC
LIMIT 11, 32
i can not use, LIMIT in NOT IN Query so, there is any way to use, or limit SELECT DISTINCT sql query, or any idea ?
Note : I need to optimise this query because, it takes so long , like a slow query.
Thanks.
Switch to NOT EXISTS( SELECT 1 FROM ... ) -- this variation does not need to compute the entire list of things; it only needs to check for the absence. LEFT JOIN .. ON .. IS NULL is also more efficient.
Furthermore, the standard schema for wp_postmeta is quite inefficient; see my suggestions.
Meanwhile, keep it as two tests, unlike the suggestion by 'holder'.
The EXISTS would look something like
AND NOT EXISTS ( SELECT 1 FROM wp_postmeta
WHERE post_id = wp_posts.id
AND meta_key = 'visible_headlane'
AND meta_value = 'On' )
which would make good use of the PRIMARY KEY(post_id, meta_key) that I recommend.
(Is it really 'headlane', not 'headline'?)
Maybe something like this as jarlh suggested
SELECT
ID,post_title,post_content,comment_count,post_date,post_status,post_name
FROM wp_posts t1
left join (
SELECT DISTINCT post_id from wp_postmeta
WHERE meta_key IN ('visible_headlane','visible_homepage') AND meta_value = 'On' ) t2 on t1.ID = t2.post_id
WHERE post_type = 'post'
AND post_status = 'publish'
AND t2.post_id is null
ORDER BY post_date DESC
LIMIT 11, 32
I'm querying the WordPress wp_postmeta table for the lowest meta_value of rows with the meta_key item_thickness:
SELECT min(cast(meta_value as unsigned)) FROM wp_postmeta WHERE meta_key='item_thickness'
This works great.
Question: How would I extend this query to select the same lowest item_thickness from rows with the same post_id and with meta_key='item_status' and meta_value='Raw'
The post_id forms the relationship between these rows but I don't know how to do a JOIN on the same table or the proper syntax for a sub-query
This is my latest (failing) attempt at the query:
SELECT *
FROM wp_postmeta
JOIN (
SELECT min(cast(meta_value as unsigned)), post_id FROM wp_postmeta WHERE meta_key='item_thickness'
) b
ON wp_postmeta.post_id=b.post_id
I was able to use WP_Query to build the MySQL I needed and then edit it so it would select the value I wanted.
Working query.
$wpdb->get_var( "SELECT min(cast(wp_postmeta.meta_value as unsigned)) FROM wp_postmeta INNER JOIN wp_posts ON ( wp_posts.ID = wp_postmeta.post_id ) INNER JOIN wp_postmeta AS mt1 ON ( wp_posts.ID = mt1.post_id ) WHERE 1=1 AND ( wp_postmeta.meta_key = 'item_thickness' AND ( mt1.meta_key = 'item_status' AND CAST(mt1.meta_value AS CHAR) = 'raw' )) AND wp_posts.post_type = 'inventory' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'future' OR wp_posts.post_status = 'draft' OR wp_posts.post_status = 'pending' OR wp_posts.post_status = 'private')" );
I have a mysql query something like this.
SELECT SQL_CALC_FOUND_ROWS wp_posts . * , wp_geodir_gd_place_detail . *
FROM wp_posts
INNER JOIN wp_geodir_gd_place_detail ON ( wp_geodir_gd_place_detail.post_id = wp_posts.ID )
INNER JOIN wp_term_relationships ON ( wp_posts.ID = wp_term_relationships.object_id )
WHERE 1 =1
AND (
wp_posts.post_status = 'publish'
OR wp_posts.post_status = 'private'
)
AND wp_posts.post_type = 'gd_place'
AND (
wp_term_relationships.term_taxonomy_id
IN ( 2, 6, 8 )
)
GROUP BY wp_posts.ID
ORDER BY wp_posts.post_title ASC , wp_posts.post_title ASC
But its returning full rows with details. Can someone help me to get the count of affected rows instead of full rows?
What is wrong with my query? Can somebody help me please?
I get this errormessage
"Unknown column 'wp_gdsr_data_article.
(SUM(user_voters)+SUM(visitor_voters))' in 'order clause'"
but the 'wp_gdsr_data_article' colum exist
SELECT *
FROM `wp_posts`
INNER JOIN wp_term_relationships ON wp_term_relationships.object_id = ID AND wp_term_relationships.term_taxonomy_id = 1
INNER JOIN wp_gdsr_data_article ON post_id = ID
WHERE `post_status` = 'publish'
AND `post_type` = 'post'
ORDER BY `wp_gdsr_data_article`.`(SUM(user_voters)+SUM(visitor_voters))` DESC
LIMIT 1 , 30
You are using an expression in the ORDER clause which not a table's column.
Hence you can't use a table identifier on the outcome of an expression.
This is wrong.
ORDER BY `wp_gdsr_data_article`.`(SUM(user_voters)+SUM(visitor_voters))` DESC
Change it to:
ORDER BY (SUM(user_voters)+SUM(visitor_voters)) DESC
And you can't directly use any aggregate function in ORDER BY clause like that.
Calculate SUM... parts separately and then use in ORDER BY.
SELECT * from (
SELECT *, (SUM(user_voters)+SUM(visitor_voters)) total
FROM `wp_posts`
INNER JOIN wp_term_relationships
ON wp_term_relationships.object_id = ID
AND wp_term_relationships.term_taxonomy_id = 1
INNER JOIN wp_gdsr_data_article
ON post_id = ID
WHERE `post_status` = 'publish'
AND `post_type` = 'post'
LIMIT 1 , 30
) results
ORDER BY total
Refer to: How to ORDER BY a SUM() in MySQL?
Remove quotes from all columns and tablenames in your statement. Besides the Order by part should base on a column or an evaluated value in our statement, the way you use it is wrong. you will need to evaluate the part which you use in the order by section before using it for the order by, something like this (untested):
SELECT (SUM(wp_gdsr_data_article.user_voters)+SUM(wp_gdsr_data_article.visitor_voters) as total_voters), *
FROM wp_posts
INNER JOIN wp_term_relationships
ON wp_term_relationships.object_id = ID
AND wp_term_relationships.term_taxonomy_id = 1
INNER JOIN wp_gdsr_data_article
ON post_id = ID
WHERE post_status = 'publish' AND post_type = 'post'
ORDER BY total_voters DESC
LIMIT 1 , 30
Try this
SELECT *, (SUM(wp_gdsr_data_article.user_voters)+SUM(wp_gdsr_data_article.visitor_voters)) AS someSum
FROM `wp_posts`
INNER JOIN wp_term_relationships ON wp_term_relationships.object_id = ID AND wp_term_relationships.term_taxonomy_id = 1
INNER JOIN wp_gdsr_data_article ON post_id = ID
WHERE `post_status` = 'publish'
AND `post_type` = 'post'
ORDER BY someSum DESC
LIMIT 1 , 30
Trying to build a somewhat complicated WordPress query. In one query, I'm trying to:
Pull all WordPress authors
Only authors with 10 or more published posts(what I'm having trouble with)
Sort authors by latest post.
Here is my original query:
SELECT wp_users.ID, display_name, user_url, user_email, MAX(post_date) as date FROM wp_users, wp_posts WHERE wp_users.ID = wp_posts.post_author AND wp_posts.post_status = 'publish' AND wp_posts.post_type = 'post' GROUP BY display_name ORDER BY date DESC;
This query returns all authors even those with 9 or less published posts.
Here is the query with the count for the posts:
SELECT wp_users.ID, display_name, user_url, user_email, MAX(post_date) as date, COUNT(post_date) as post_count FROM wp_users, wp_posts WHERE wp_users.ID = wp_posts.post_author AND wp_posts.post_status = 'publish' AND wp_posts.post_type = 'post' GROUP BY display_name ORDER BY date DESC;
In this query you can see that I've added:
COUNT(post_date) as post_count
Which returns everything beautifully.
It's only when I add this WHERE clause, does the query break
post_count > 9
I get this error message:
Unknown column 'post_count' in 'where clause'
Any idea why this is happing? My theories:
Won't work with grouping
or MySQL doesn't allow more than one AS statement
If you could shed some light, I would greatly appreciate it.
Thanks.
change the condition in the WHERE part of the query post_count > 9
with HAVING post_count > 9 after the GROUP BY
the final query will be SELECT wp_users.ID, display_name, user_url, user_email, MAX(post_date) as date, COUNT(post_date) as post_count FROM wp_users, wp_posts WHERE wp_users.ID = wp_posts.post_author AND wp_posts.post_status = 'publish' AND wp_posts.post_type = 'post' GROUP BY display_name HAVING post_count > 9 ORDER BY date DESC;
You're looking for the "HAVING" operator.
SELECT wp_users.ID, display_name, user_url, user_email, MAX(post_date) as date, COUNT(post_date) as post_count FROM wp_users, wp_posts WHERE wp_users.ID = wp_posts.post_author AND wp_posts.post_status = 'publish' AND wp_posts.post_type = 'post' GROUP BY display_name HAVING post_count>9 ORDER BY date DESC;