WordPress SQL Custom Query To Get Post, Post Meta Data, Category and Featured Image of the post.
I've tried so far the below code and got the post and post meta data. Now taxonomy and featured image remaining:
$query = mysql_query("
SELECT wp_posts.ID
, wp_posts.post_title
, mt1.meta_value as latitude
, mt2.meta_value as longitude
, mt3.meta_value as full_adddress
FROM wp_posts
LEFT JOIN wp_postmeta AS mt1 ON (wp_posts.ID = mt1.post_id AND mt1.meta_key='lv_listing_lat')
LEFT JOIN wp_postmeta AS mt2 ON (wp_posts.ID = mt2.post_id AND mt2.meta_key='lv_listing_lng')
LEFT JOIN wp_postmeta AS mt3 ON (wp_posts.ID = mt3.post_id AND mt3.meta_key='_address')
WHERE wp_posts.post_type = 'lv_listing'
AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private')
AND ((mt1.meta_key = 'lv_listing_lat') OR (mt2.meta_key = 'lv_listing_lng' ) OR (mt3.meta_key = '_address' ))
GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC ");
Revised code by myself. In this code category achieved, now only featured image attachment url needed.
SELECT DISTINCT
ID, post_title
, post_content
,(SELECT meta_value FROM wp_postmeta WHERE wp_postmeta.meta_key = 'lv_listing_lat' AND wp_postmeta.post_id = wp_posts.ID) AS "lv_listing_lat"
,(SELECT meta_value FROM wp_postmeta WHERE wp_postmeta.meta_key = 'lv_listing_lng' AND wp_postmeta.post_id = wp_posts.ID) AS "lv_listing_lng"
,(SELECT group_concat(wp_terms.name separator ', ')
FROM wp_terms
INNER JOIN wp_term_taxonomy on wp_terms.term_id = wp_term_taxonomy.term_id
INNER JOIN wp_term_relationships wpr on wpr.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
WHERE taxonomy= 'listing_category' and wp_posts.ID = wpr.object_id
) AS "Listing Category"
,(SELECT group_concat(wp_terms.name separator ', ')
FROM wp_terms
INNER JOIN wp_term_taxonomy on wp_terms.term_id = wp_term_taxonomy.term_id
INNER JOIN wp_term_relationships wpr on wpr.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
WHERE taxonomy= 'listing_location' and wp_posts.ID = wpr.object_id
) AS "Listing Location"
FROM wp_posts
WHERE post_type = 'lv_listing'
ORDER BY
post_title
, post_content
Related
With this query i get the posts i need from my wordpress db. What i have to do to get the posts from a specific category?
$sql = "select DISTINCT wp_posts.id, wp_posts.post_title, wp_posts.post_excerpt, wp_posts.guid, wp_posts.post_type, featured_image.guid as post_image, wp_posts.post_modified, wp_users.display_name
from wp_posts
inner join wp_postmeta on wp_posts.id = wp_postmeta.post_id and wp_postmeta.meta_key = '_thumbnail_id'
inner join wp_posts as featured_image on featured_image.id = wp_postmeta.meta_value
inner join wp_users on wp_users.id = wp_posts.post_author
where wp_posts.post_status = 'publish'
AND DATE_FORMAT(wp_posts.post_date, '%d-%m-%Y')='$mydate'
order by wp_posts.ID desc
limit 20";
You have to have joins with three more tables: wp_term_relationships, wp_term_taxonomy and wp_terms, and in the where clause you can search for the category name from the name column of the terms table. Have updated the sql query
$sql = "select DISTINCT wp_posts.id, wp_posts.post_title, wp_posts.post_excerpt, wp_posts.guid, wp_posts.post_type, featured_image.guid as post_image, wp_posts.post_modified, wp_users.display_name
from wp_posts
inner join wp_postmeta on wp_posts.id = wp_postmeta.post_id and wp_postmeta.meta_key = '_thumbnail_id'
inner join wp_posts as featured_image on featured_image.id = wp_postmeta.meta_value
inner join wp_users on wp_users.id = wp_posts.post_author
INNER JOIN wp_term_relationships rel ON wp_posts.ID = rel.object_id
INNER JOIN wp_term_taxonomy taxonomy ON rel.term_taxonomy_id = taxonomy.term_taxonomy_id
INNER JOIN wp_terms terms ON taxonomy.term_id = terms.term_id
where wp_posts.post_status = 'publish'
AND terms.name = 'Category you wist to search for'
AND DATE_FORMAT(wp_posts.post_date, '%d-%m-%Y')='$mydate'
order by wp_posts.ID desc
limit 20";
I use this SQL query to get me all the posts that don't have a photo, it shows me 2010 posts, however with what SQL command I can delete those 2010 posts
SELECT *
FROM wp_posts
LEFT JOIN wp_postmeta ON wp_posts.ID = wp_postmeta.post_id
AND wp_postmeta.meta_key = '_thumbnail_id'
WHERE 1 = 1 AND wp_postmeta.post_id IS NULL
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.post_date
One option would be using EXISTS :
DELETE FROM wp_posts
WHERE EXISTS
(
SELECT 1
FROM wp_posts wp1
LEFT JOIN wp_postmeta wp2 ON wp1.ID = wp2.post_id AND wp2.meta_key = '_thumbnail_id'
WHERE wp2.post_id IS NULL
AND wp1.post_type = 'post'
AND (wp1.post_status = 'publish' OR wp1.post_status = 'private')
AND wp1.ID = wp_posts.ID
GROUP BY wp1.ID
)
or an INNER JOIN :
DELETE w
FROM wp_posts w JOIN
(
SELECT wp1.ID
FROM wp_posts wp1
LEFT JOIN wp_postmeta wp2 ON wp1.ID = wp2.post_id AND wp2.meta_key = '_thumbnail_id'
WHERE wp2.post_id IS NULL
AND wp1.post_type = 'post'
AND (wp1.post_status = 'publish' OR wp1.post_status = 'private')
GROUP BY wp1.ID
) w2
ON w.ID = w2.ID
I've been trying to figure out how to get the wp_meta_value depending on the term ID.
This is where I'm at so far but my head is spinning now! If you can help, I'd much appreciate it :)
Thanks
SELECT wp_posts.post_title
FROM wp_posts
LEFT JOIN wp_term_relationships ON (
wp_posts.ID = wp_term_relationships.object_id
)
LEFT JOIN wp_term_taxonomy ON (
wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
)
WHERE wp_posts.post_status = 'publish'
AND wp_term_taxonomy.term_id =2
ORDER BY post_title DESC
LIMIT 0 , 30
This seems to work...
SELECT wp_posts.post_title, wp_postmeta.meta_value AS 'Contact Details'
FROM wp_posts
LEFT JOIN wp_term_relationships ON ( wp_posts.ID = wp_term_relationships.object_id )
LEFT JOIN wp_term_taxonomy ON ( wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id )
LEFT JOIN wp_postmeta ON ( wp_postmeta.post_id = wp_posts.ID )
WHERE wp_posts.post_status = 'publish'
AND wp_postmeta.meta_key = 'contact'
AND wp_term_taxonomy.term_id =2
ORDER BY post_title;
In a WordPress installation, I need to order products so that:
Sold products show up last.
Sold products tagged "antique" show up after sold products tagged "reproduction."
I have successfully completed the first item, but I am at a loss regarding the second item. I'm not getting any errors. My problem is that everything in my ORDER BY statement is working except for "wt.slug DESC." If I change the LEFT JOIN statements for wp_term_taxonomy and wp_terms tables to INNER JOIN statements, I get 0 results, so it looks to me like these statements are not finding the results that I expect. Here is my query:
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID
FROM wp_posts
INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id )
LEFT JOIN wp_postmeta stock ON ( wp_posts.ID = stock.post_id AND stock.meta_key = '_stock_status' )
LEFT JOIN wp_term_taxonomy wtt ON ( wp_term_relationships.term_taxonomy_id = wtt.term_taxonomy_id AND wtt.taxonomy = 'product_tag' )
LEFT JOIN wp_terms wt ON ( wtt.term_id = wt.term_id AND ( wt.slug = 'antique' OR wt.slug = 'reproduction' ) )
WHERE 1=1
AND ( wp_term_relationships.term_taxonomy_id IN (171) )
AND ( ( wp_postmeta.meta_key = '_visibility' AND CAST(wp_postmeta.meta_value AS CHAR) IN ('visible','catalog') ) )
AND wp_posts.post_type = 'product'
AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private')
GROUP BY wp_posts.ID
ORDER BY wp_posts.post_type DESC, stock.meta_value ASC, wt.slug DESC, wp_posts.post_date
Here is the WordPress database description for reference. I would appreciate any assistance.
You can create a new field as
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID, CASE wt.slug WHEN 'antique' THEN -1 WHEN 'reproduction' THEN 0 ELSE 1 END as sort_order
and use the sort_order in ORDER BY clause like
ORDER BY sort_order DESC
Thanks to help from #mynawaz, I have been able to come up with a solution. I'm not sure if it's the most efficient or elegant solution, but it works:
SELECT SQL_CALC_FOUND_ROWS wp_posts.* , CASE wt.slug WHEN 'antique' THEN 1 WHEN 'reproduction' THEN 2 ELSE 0 END as slug_order
FROM wp_posts
INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id )
LEFT JOIN wp_postmeta stock ON ( wp_posts.ID = stock.post_id AND stock.meta_key = '_stock_status' )
LEFT JOIN wp_term_relationships wtr ON ( wp_posts.ID = wtr.object_id AND stock.meta_value = 'outofstock' )
LEFT JOIN wp_term_taxonomy wtt ON ( wtr.term_taxonomy_id = wtt.term_taxonomy_id AND wtt.taxonomy = 'product_tag' )
LEFT JOIN wp_terms wt ON ( wtt.term_id = wt.term_id AND wt.slug IN( 'antique','reproduction' ) )
WHERE 1=1
AND ( wp_term_relationships.term_taxonomy_id IN (171) )
AND ( ( wp_postmeta.meta_key = '_visibility' AND CAST(wp_postmeta.meta_value AS CHAR) IN ('visible','catalog') ) )
AND wp_posts.post_type = 'product'
AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private')
AND NOT (
stock.meta_value = 'outofstock'
AND ( CASE wt.slug WHEN 'antique' THEN 1 WHEN 'reproduction' THEN 2 ELSE 0 END ) = 0
)
GROUP BY wp_posts.ID, slug_order
ORDER BY wp_posts.post_type DESC, stock.meta_value ASC, slug_order DESC, wp_posts.post_date DESC
I need to extract all posts from my WordPress DB along with the associated categories and not sure how to write this query. I've taken a couple of stabs at it already with no joy and would appreciate the help?
EDIT: Here's what I have tried already:
SELECT post_title, wpr.object_id, wp_terms.name
FROM wp_terms
INNER JOIN wp_term_taxonomy ON wp_terms.term_id = wp_term_taxonomy.term_id
INNER JOIN wp_term_relationships wpr ON wpr.term_taxonomy_id =
wp_term_taxonomy.term_taxonomy_id
INNER JOIN wp_posts ON ID = wpr.object_id
WHERE taxonomy = 'category'
AND post_type = 'post'
ORDER by post_title
This seems to work but it returns 1,553 where I know I only have 1343 in my DB.
EDIT:
We did the same thing on another SQL query a little while ago and found that it was pulling in the revisions and other post types but thought that this was resolved using post_type = 'post'
EDIT:
Upon looking at the number of categories in the DB, I come up with a total number of 216, 6 off the number if you subtract 1553 - 1343 = 216. So I think this total number of 1553 is coming from the wp_terms table which needs to be excluded and only those that are active with published posts should be shown?
EDIT:
The other possibility is that each post can have multiple categories, hence the reason for having more posts (1553). So how could I separate each posts into multiple categories?
Many thanks!
This is the final answer that worked for me.
SELECT DISTINCT
post_title
, post_content
,(SELECT meta_value FROM wp_postmeta WHERE wp_postmeta.meta_key = 'Asking Price (US\$)' AND wp_postmeta.post_id = wp_posts.ID) AS "Asking Price (US\$)"
,(SELECT group_concat(wp_terms.name separator ', ')
FROM wp_terms
INNER JOIN wp_term_taxonomy on wp_terms.term_id = wp_term_taxonomy.term_id
INNER JOIN wp_term_relationships wpr on wpr.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
WHERE taxonomy= 'category' and wp_posts.ID = wpr.object_id
) AS "Categories"
,(SELECT group_concat(wp_terms.name separator ', ')
FROM wp_terms
INNER JOIN wp_term_taxonomy on wp_terms.term_id = wp_term_taxonomy.term_id
INNER JOIN wp_term_relationships wpr on wpr.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
WHERE taxonomy= 'post_tag' and wp_posts.ID = wpr.object_id
) AS "Tags"
FROM wp_posts
WHERE post_type = 'post'
ORDER BY
post_title
, post_content
/* Query for fetch post/posts using post user, post category and post_title */
$query ="SELECT wp_posts.post_title, wp_posts.post_content, wp_posts.comment_count, wp_users.display_name, wp_terms.name
FROM wp_posts
JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
JOIN wp_term_taxonomy ON (wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id)
LEFT JOIN wp_terms ON (wp_terms.term_id = wp_term_taxonomy.term_id)
JOIN wp_users ON (wp_posts.post_author = wp_users.ID)
WHERE wp_term_taxonomy.term_id IN ($bycat)
AND wp_users.ID = $byuser
AND wp_posts.post_type = 'post'
AND (wp_posts.post_content LIKE '$bytitle' OR wp_posts.post_title LIKE '$bytitle')
AND wp_posts.post_status = 'publish'
ORDER BY wp_posts.post_modified DESC";
/*---- FOR DISPLAY RESULT -----*/
$resultfirst = $wpdb->get_results($query);
foreach( $resultfirst as $result ){
echo $result->post_title .'';
echo $result->display_name.'';
echo $result->name.'';
echo $result->comment_count.'';
}