Querying WordPress DB from normal sql - mysql

Disclaimer: I am not going to use any other ways I have a specific requirement.
All I want is to Join from posts table to the posts meta so that I can get the featured image per post. I am able to get the post via where clause post type is post and published but I don't know how to write join for MySql to get the featured image of each post

You may try something like this:
$sql = "
SELECT $wpdb->posts.*
FROM $wpdb->posts, $wpdb->postmeta
WHERE $wpdb->posts.ID = $wpdb->postmeta.post_id
AND $wpdb->posts.post_status = 'publish'
AND $wpdb->posts.post_type = 'post'
ORDER BY $wpdb->posts.post_date DESC
";
// Get an array of objects
$posts = $wpdb->get_results($sql, OBJECT);
You may check more here.

If someone else is still looking for the sql needed here you go
SET #term = "someterm"
SELECT DISTINCT
posts.id,
posts.post_author,
posts.post_title,
posts.post_date,
LEFT(posts.post_content,300) post_content,
wpmeta.meta_value thumbnail
FROM wp_posts posts
INNER JOIN wp_postmeta wpm ON posts.id = wpm.post_id
INNER JOIN wp_postmeta wpmeta ON wpm.meta_value = wpmeta.post_id
LEFT JOIN wp_term_relationships rel ON rel.object_id = posts.ID
LEFT JOIN wp_term_taxonomy tax ON tax.term_taxonomy_id = rel.term_taxonomy_id
LEFT JOIN wp_terms t ON t.term_id = tax.term_id
WHERE
post_status = 'publish'
AND posts.post_type = 'post'
AND wpm.meta_key = '_thumbnail_id'
AND wpmeta.meta_key = '_wp_attached_file'
AND 1 =
CASE
WHEN #term IS NULL THEN 1
WHEN #term IS NOT NULL AND t.term_id = #term THEN 1
ELSE 0
END
ORDER BY post_date DESC

Related

Filter rows without a specific value

I'm querying a wordpress mysql db outside the php language and I don't know how to solve the following problem: each post has taxonomies with some value. There's a value called 'calificaciones' which I'd like to filter on. This is my current query:
SELECT wp_posts.post_title, IF (wp_term_taxonomy.taxonomy = 'calificaciones', wp_terms.slug, 'no') as calificacion
FROM wp_posts
JOIN wp_term_relationships ON (wp_term_relationships.object_id = wp_posts.ID)
JOIN wp_term_taxonomy ON (wp_term_taxonomy.term_taxonomy_id = wp_term_relationships.term_taxonomy_id)
JOIN wp_terms ON (wp_terms.term_id = wp_term_taxonomy.term_id)
AND wp_posts.post_type = 'ultimas-noticias'
#AND wp_term_taxonomy.taxonomy = 'calificaciones'
The problem with this query is that I'll get the post_title multiple times(because there are others taxonomies for each post). I'd like to get the post title and a flag yes-no, if the post has that taxonomy value or not.
Instead of joining the taxonomies on the same query you could use a sub query for the calificacion column.
SELECT wp_posts.post_title, CASE WHEN EXISTS((SELECT *
FROM wp_term_relationships
JOIN wp_term_taxonomy ON (wp_term_taxonomy.term_taxonomy_id = wp_term_relationships.term_taxonomy_id)
JOIN wp_terms ON (wp_terms.term_id = wp_term_taxonomy.term_id)
WHERE (wp_term_relationships.object_id = wp_posts.ID)
AND wp_term_taxonomy.taxonomy = 'calificaciones'
)) THEN 'YES' ELSE 'NO' END as calificacion
FROM wp_posts
WHERE wp_posts.post_type = 'ultimas-noticias'
You can use select distinct
SELECT distinct wp_posts.post_title, IF (wp_term_taxonomy.taxonomy = 'calificaciones', wp_terms.slug, 'no') as calificacion
FROM wp_posts
JOIN wp_term_relationships ON (wp_term_relationships.object_id = wp_posts.ID)
JOIN wp_term_taxonomy ON (wp_term_taxonomy.term_taxonomy_id = wp_term_relationships.term_taxonomy_id)
JOIN wp_terms ON (wp_terms.term_id = wp_term_taxonomy.term_id)
AND wp_posts.post_type = 'ultimas-noticias'
#AND wp_term_taxonomy.taxonomy = 'calificaciones'

MySQL left join needed on Wordpress database

I'm new to MySQL and ended up with this statement on a standard Wordpress database to get the latest articles.
However, the statement below requires that related rows are found in [wp_postmeta] to get the thumbnail belonging to the article.
However, some posts may not have a thumbnail but I still want to select those.
How can I alter the statement to not require a thumbnail value in [wp_postmeta]? I believe I need a left join clause, but don't know how to do it.
SELECT p.*, ( SELECT guid FROM wp_posts WHERE id = m.meta_value ) AS imgurl
FROM wp_posts p, wp_postmeta m
WHERE p.post_type = 'post'
AND p.post_status = 'publish'
AND p.id = m.post_id
AND m.meta_key = '_thumbnail_id'
ORDER BY post_date DESC
Try this with join and ON(p.id = m.post_id AND m.meta_key = '_thumbnail_id' )
SELECT DISTINCT p.*, ( SELECT guid FROM wp_posts WHERE id = m.meta_value LIMIT 1) AS imgurl
FROM wp_posts p
LEFT JOIN wp_postmeta m ON(p.id = m.post_id AND m.meta_key = '_thumbnail_id' )
WHERE p.post_type = 'post'
AND p.post_status = 'publish'
ORDER BY post_date DESC
Use this query it will fetch latest 5 post, you can increase the display limit.
$sql = " SELECT * FROM wp_posts p
WHERE p.post_type = 'post'
AND p.post_status = 'publish'
AND p.post_type = 'post'
ORDER BY p.post_date DESC
LIMIT 5";

Wordpress custom SQL to fecth three posts with given meta values

I have bunch of custom post type footer elements with a meta key footer_element_meta_alignment. Now, I'm trying to fetch three latest posts, which meta_values are 1, 2 and 3. So, one post with each of those values.
How can I achieve this with single SQL Query?
This is my SQL Query so far:
"SELECT wposts.*, meta1.meta_value
FROM $wpdb->posts wposts, $wpdb->postmeta meta1
WHERE 1=1
AND wposts.post_type = 'footer_element'
AND wposts.post_status = 'publish'
AND wposts.ID = meta1.post_id
AND meta1.meta_key = 'footer_element_meta_alignment'
AND (meta1.meta_value = 1 OR meta1.meta_value = 2 OR meta1.meta_value = 3)
ORDER BY meta1.meta_value ASC";
That however fetches all elements with given meta values, and not only the latest one.
ANSWER
Answered my own question.
After struggling few hours I found a solution for this.
SQL
"SELECT *
FROM ( SELECT p.*, m.meta_value AS meta
FROM $wpdb->posts AS p
LEFT JOIN $wpdb->postmeta AS m
ON p.ID = m.post_id
WHERE m.meta_key = 'footer_element_meta_alignment'
AND p.post_status = 'publish'
ORDER BY m.meta_value ASC, p.post_date DESC) AS h
GROUP BY meta";
Fixed (I hope).
SELECT wposts.* FROM $wpdb->posts wposts WHERE
wposts.post_type = 'footer_element'
AND wposts.post_status = 'publish'
AND wposts.ID IN
(SELECT max(meta1.post_id) FROM $wpdb->postmeta meta1
WHERE meta1.meta_value = 1 OR meta1.meta_value = 2 OR meta1.meta_value = 3
GROUP BY meta1.meta_value)

How to merge two SQL queries to get latest Wordpress Post and Featured Image

I'm trying to show latest Post Excerpt, Post Title and Featured Image on an ASP page. To simplify the query I add the Permalink as a custom field for each Post. I have a query that gets all except Featured Image and I have another query that gets Featured image but I can't work out how to merge them into one query.
// Gets Post Excerpt and Post Title
SELECT
wp_posts.id,
wp_posts.post_title,
wp_postmeta.meta_value,
wp_postmeta.meta_key,
wp_posts.post_excerpt
FROM
wp_postmeta
INNER JOIN wp_posts p ON (wp_postmeta.post_id = wp_posts.ID)
WHERE post_id IN (
SELECT wp_posts.id
FROM wp_posts
WHERE post_type = 'post'
AND post_status = 'publish'
AND meta_key = 'my_permalink'
ORDER BY post_date, wp_posts.id
)
ORDER BY wp_posts.post_date DESC, wp_postmeta.post_id
LIMIT 2
// Gets Featured Images for a Post
SELECT p.*
FROM wp_postmeta AS pm
INNER JOIN wp_posts AS p ON pm.meta_value=p.ID
WHERE pm.post_id = $ID
AND pm.meta_key = '_thumbnail_id'
ORDER BY p.post_date DESC
Can anyone help me merge these queries? Thanks.
Sample data to be returned:
ID | post_title | post_excerpt | meta_value_my_permalink | featured_image_guid
** UPDATE *
I've managed to get the following which works fine except I can't get more that one row as I get an error when I try and use 'IN' in a subquery
e.g. pm2.post_id IN (SELECT wp_posts.id FROM wp_posts WHERE post_type = 'post' AND post_status = 'publish' ORDER BY post_date DESC LIMIT 2)
SELECT
p.post_title,
p.post_excerpt,
pm.meta_value AS permalink,
p2.guid as thumbnail,
p2.post_title as image_alt
FROM
wp_postmeta pm
INNER JOIN wp_posts p ON (pm.post_id = p.ID),
wp_postmeta pm2
INNER JOIN wp_posts p2 ON (pm2.meta_value = p2.ID)
WHERE
pm.post_id = (SELECT wp_posts.id FROM wp_posts WHERE post_type = 'post' AND post_status = 'publish' ORDER BY post_date DESC LIMIT 1) AND
pm.meta_key = 'my_permalink' AND
pm2.post_id = (SELECT wp_posts.id FROM wp_posts WHERE post_type = 'post' AND post_status = 'publish' ORDER BY post_date DESC LIMIT 1) AND
pm2.meta_key = '_thumbnail_id'
It is difficult to see what you are trying to get without some sample data but I think that you know the post ID and need the info from both the my_permakink and _thumbnail_id keys?
Since I'm on a tablet I will give you the bare bones only and let you limit the result set and filter it.
Select *
From wp_posts p
Inner join
Wp_postmeta pm1 on p.id = pm1.post_id and metakey = 'my_permalink'
Inner join
Wp_postmeta pm2 on p.id = pm1.post_id and metakey = '_thumbnail_id'
This will give you every post that has an image with the info for both metakeys. If you want the info for posts without an image change the second inner join to a left join.
A bunch of joins and a view as the subquery has given me what I need.
SELECT
p.post_title,
p.post_excerpt,
pm.meta_value AS permalink,
p2.guid AS thumbnail,
p2.post_title AS thumbnail_alt
FROM
wp_postmeta pm
INNER JOIN wp_posts p ON (pm.post_id = p.ID)
INNER JOIN wp_postmeta pm2 ON (pm2.post_id = p.ID)
INNER JOIN wp_posts p2 ON (pm2.meta_value = p2.ID)
WHERE
pm.meta_key = 'my_permalink' AND
pm2.meta_key = '_thumbnail_id' AND
p.ID IN (SELECT * FROM vwLatestPostIds)
Use this to retrieve the post title, post id, post featured thumbnail url, post category etc -
"SELECT a.ID id, a.post_title title, a.post_content content,taxonomy, name, a.post_date_gmt postdate,max(c.guid) img_url
FROM kb_posts a
JOIN kb_term_relationships tr
ON (a.id = tr.object_id)
JOIN kb_term_taxonomy tt
ON (tr.term_taxonomy_id = tt.term_taxonomy_id AND tt.taxonomy='category')
JOIN kb_terms t
ON (t.term_id = tt.term_id AND t.term_id = $user_id)
LEFT JOIN
(select post_parent, max(post_date_gmt) as latest_image_date from kb_posts
where post_type='attachment' GROUP BY post_parent) b
on a.id=b.post_parent
LEFT JOIN kb_posts c
on c.post_parent=a.id
and c.post_type='attachment'
and b.latest_image_date = c.post_date_gmt where c.guid IS NOT NULL
GROUP BY a.ID ORDER BY a.ID DESC LIMIT 5"

SQL query to extract all WordPress posts with categories

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.'';
}