I have to make a mysql select from a wordpress database :
SELECT wp_posts.ID, wp_posts.post_title AS post_title,
responsable.meta_value AS responsable,
nif_cliente.meta_value AS nif_cliente,
CONCAT_WS(' ',contactos_0_nombre.meta_value,CONCAT('<br><br>',contactos_1_nombre.meta_value)) AS contactos,
tipo_de_empresa.meta_value AS tipo_de_empresa,
tipo_cliente.meta_value AS tipo_cliente
FROM wp_posts
LEFT JOIN wp_postmeta AS responsable
ON wp_posts.ID = responsable.post_id AND responsable.meta_key='responsable'
LEFT JOIN wp_postmeta AS tipo_de_empresa
ON wp_posts.ID = tipo_de_empresa.post_id AND tipo_de_empresa.meta_key='tipo_de_empresa'
LEFT JOIN wp_postmeta AS nif_cliente
ON wp_posts.ID = nif_cliente.post_id AND nif_cliente.meta_key='nif_cliente'
LEFT JOIN wp_postmeta AS contactos_0_nombre
ON wp_posts.ID = contactos_0_nombre.post_id AND contactos_0_nombre.meta_key='contactos_0_nombre'
LEFT JOIN wp_postmeta AS contactos_1_nombre
ON wp_posts.ID = contactos_1_nombre.post_id AND contactos_1_nombre.meta_key='contactos_1_nombre'
LEFT JOIN wp_postmeta AS tipo_cliente
ON wp_posts.ID = tipo_cliente.post_id AND tipo_cliente.meta_key='tipo_cliente'
WHERE wp_posts.post_status = 'publish' AND wp_posts.post_type = 'clientes'"
I want to concate contactos_n_nombre. I can write it manual but 'n' it's dinamic (i don't know how much it is) It can be 0 if there are only one contact, but can be 1000 if this client have more contact methods.
How can i make it to search how many contactos have one client, and concate all of them
Thanks
If I understand your question correctly, you can use the MySQL GROUP_CONCAT function. You may need to adjust this for your situation, but the basic idea is:
Set up the database JOIN as:
LEFT JOIN wp_postmeta AS contactosdb ON wp_posts.ID = contactosdb.post_id
Then use the following in your SELECT:
GROUP_CONCAT(contactosdb.meta_value SEPARATOR '<br><br>') AS contactos
Related
I am trying to SELECT (all of the multiple) comments from Wordpress which relate to a post (wp_comments.comment_content) with GROUP_CONCAT but I only want to select those comments which DON'T contain the text string "status". If there are no comments at all, or only comments which contain "status" I still want to see those records in the result, just without getting anything back for comments.
When I tried putting a condition similar to [WHERE wp_comments.comment_content NOT LIKE "%status%"] at the end of the complete query, records which only have a comment containing "status" don't display AT ALL, I still need to get those records, just without the comments.
I want to try something like the below version but this throws up an error and doesn't spit out any data at all. (The overall query works as expected btw apart from the comment selection section..).
Maybe I am joining the wp_comments table in the wrong place, using the wrong join, not using a properly formatted nested SELECT or similar, maybe it needs a separate SELECT at the end so I can get the comments back I want in a way which doesn't effect which records are selected overall.. not sure..
Any idea what I am doing wrong or how to approach this?
Here is my query, thanks in advance for any kind pointers!
select wp_woocommerce_order_itemmeta.meta_value as firstwoometavalue,
wp_postmeta.meta_value as firstwpmetavalue, Y.meta_value as ymetavalue,
Z.meta_value as zmetavalue, X.meta_value as xmetavalue,
(GROUP_CONCAT(wp_comments.comment_content) as commentcontent
WHERE wp_comments.comment_type = "order_note" AND
wp_comments.comment_content NOT LIKE "%status%")
FROM wp_postmeta
left JOIN wp_postmeta as Y
ON wp_postmeta.post_id = Y.post_id
left JOIN wp_posts
ON wp_postmeta.post_id = wp_posts.ID
left JOIN wp_woocommerce_order_items
ON wp_woocommerce_order_items.order_id = wp_posts.ID
left JOIN wp_woocommerce_order_itemmeta
ON wp_woocommerce_order_itemmeta.order_item_id = wp_woocommerce_order_items.order_item_id
left JOIN wp_woocommerce_order_itemmeta as Z
ON wp_woocommerce_order_itemmeta.order_item_id = Z.order_item_id
left JOIN wp_woocommerce_order_itemmeta as X
ON wp_woocommerce_order_itemmeta.order_item_id = X.order_item_id
left JOIN wp_comments
ON wp_comments.comment_post_ID = wp_posts.ID
where 1=1
AND wp_woocommerce_order_itemmeta.meta_key ="Adults"
AND wp_postmeta.meta_key ="_billing_first_name"
AND Y.meta_key ="_billing_last_name"
AND Z.meta_key ="Booking Type"
AND Z.meta_value LIKE "%'.$showlocation.'%"
AND X.meta_key ="Booking Date"
AND X.meta_value = "'.$showdate.'"
AND wp_posts.post_status ="wc-completed"
GROUP BY wp_posts.ID
This works
SELECT
wp_woocommerce_order_itemmeta.meta_value AS Adults,
wp_postmeta.meta_value AS FirstName,
jn_postmeta_lastname.meta_value AS LastName,
jn_woocommerce_order_itemmeta_location.meta_value AS Location,
jn_woocommerce_order_itemmeta_date.meta_value AS ShowDate,
(SELECT
GROUP_CONCAT(wp_comments.comment_content)
FROM
wp_comments
WHERE
wp_comments.comment_content NOT LIKE '%status%'
AND wp_comments.comment_post_ID = wp_posts.ID) Notes
FROM
wp_postmeta
LEFT JOIN
wp_postmeta AS jn_postmeta_lastname ON wp_postmeta.post_id = jn_postmeta_lastname.post_id
LEFT JOIN
wp_posts ON wp_postmeta.post_id = wp_posts.ID
LEFT JOIN
wp_woocommerce_order_items ON wp_woocommerce_order_items.order_id = wp_posts.ID
LEFT JOIN
wp_woocommerce_order_itemmeta ON wp_woocommerce_order_itemmeta.order_item_id = wp_woocommerce_order_items.order_item_id
LEFT JOIN
wp_woocommerce_order_itemmeta AS jn_woocommerce_order_itemmeta_location ON wp_woocommerce_order_itemmeta.order_item_id = jn_woocommerce_order_itemmeta_location.order_item_id
LEFT JOIN
wp_woocommerce_order_itemmeta AS jn_woocommerce_order_itemmeta_date ON wp_woocommerce_order_itemmeta.order_item_id = jn_woocommerce_order_itemmeta_date.order_item_id
LEFT JOIN
wp_comments ON wp_comments.comment_post_ID = wp_posts.ID
WHERE
1 = 1
AND (wp_postmeta.meta_key = '_billing_first_name'
AND jn_postmeta_lastname.meta_key = '_billing_last_name'
AND wp_woocommerce_order_itemmeta.meta_key = 'Adults'
AND jn_woocommerce_order_itemmeta_location.meta_key = 'Booking Type'
AND jn_woocommerce_order_itemmeta_location.meta_value LIKE "%'.$showlocation.'%"
AND jn_woocommerce_order_itemmeta_date.meta_key = 'Booking Date'
AND jn_woocommerce_order_itemmeta_date.meta_value = "'.$showdate.'"
AND wp_posts.post_status = 'wc-completed'
GROUP BY wp_posts.ID
I've have two sql queries which I'm trying to combine
The first:
SELECT * FROM wp_posts
JOIN wp_postmeta on (post_id=ID)
WHERE meta_key = "packageID" and meta_value = 1
ORDER BY post_date limit 50
Joins the wordpress wp_post table to the wp_postmeta and gets all the posts meeting with packageID = 1 (I think it might be an inelegant way of doing it but it works)
The second
SELECT * FROM wp_postmeta
JOIN wp_posts ON (meta_value=ID)
WHERE post_id = 2110
AND meta_key = '_thumbnail_id'
again joins the wp_post table to the wp_postmeta table, so for the post with the id 2110 it successfully gets the thumbnail for that posts. NB 2110 is just an example of an id
In Wordpress a thumbnail is a kind of post. So in this example the text which constitutes post 2110 is a associated with post 2115 - the latter being the thumbnail
What I'm trying to do is get the list as in the first query but also get thumbnails associated with each post
I think I need two joins but I can't see how to do it (being an sql beginner)
NB this will be in a script outside Wordpress so I can't use Wordpress's built-in functions
You can try this one,if there are more than one thumbnails for the post you can get the list of thumbnails separated by comma
SELECT
*,
(SELECT
GROUP_CONCAT(meta_value)
FROM
wp_postmeta
WHERE post_id = wp.ID
AND wpm.meta_key = "_thumbnail_id") AS `thumbnails`
FROM
wp_posts wp
JOIN wp_postmeta wpm
ON (wpm.post_id = wp.ID)
WHERE wpm.meta_key = "packageID"
AND wpm.meta_value = 1
ORDER BY wp.post_date
LIMIT 50
Note : GROUP_CONCAT has a limit to concat characters but you
can increase this limit
To get only one thumbnail you can try this
SELECT
*,
(SELECT
(meta_value)
FROM
wp_postmeta
WHERE post_id = wp.ID
AND wpm.meta_key = "_thumbnail_id" LIMIT 1)
FROM
wp_posts wp
JOIN wp_postmeta wpm
ON (wpm.post_id = wp.ID)
WHERE wpm.meta_key = "packageID"
AND wpm.meta_value = 1
ORDER BY wp.post_date
LIMIT 50
try with the following code
SELECT * FROM wp_posts wp JOIN wp_postmeta wm on (wp.post_id=wm.ID) WHERE wp.meta_key = "packageID" and wp.meta_value = 1 ORDER BY wp.post_date limit 50;
use proper alias and try it.
Try using the post_type column. The attachments have a post_type of 'attachment'. I can further explain if needed.
Also the post to which the thumbnail is attached to will be in the column post_parent.
global $wpdb;
$query7 = "SELECT distinct wp_postmeta.meta_value, wp_postmeta.meta_key, wp_posts.ID
FROM wp_posts INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id)
INNER JOIN wp_postmeta AS mt1 ON (wp_posts.ID = mt1.post_id)
WHERE wp_posts.ID = wp_postmeta.post_id
AND wp_posts.post_status = 'publish'
AND wp_postmeta.meta_key = 'packageID'
AND wp_postmeta.meta_value = 1
AND (mt1.meta_key LIKE '_thumbnail_id')
$output = $wpdb->get_results( $query7 );
Use join with different aliases when joining same table more than once.
Hope this helps.
Try this
SELECT * FROM wp_posts P1
LEFT JOIN wp_postmeta M1 ON (M1.post_id=P1.ID)
WHERE (M1.meta_key = "packageID" and M1.meta_value = 1 )
LEFT JOIN wp_postmeta M2 ON (M2.meta_key=P1.ID AND M2.meta_key = '_thumbnail_id')
LEFT JOIN wp_posts P2 ON (M2.meta_value=P2.ID)
ORDER BY P1.post_date limit 50
I need to select some things from few WP tables, one of which is custom field value with a certain key. Problem is, some of posts don't have custom field with this key but aside of that they match query. So question is, how do I select even posts that doesn't have custom field with this key, but other than that match query? Value of field for the posts that do not have custom field should be set 0. I figured it's something like COALESCE, but I'm either using it wrong or it can't be used in this case. My query so far is:
select lists.id,lists.`type`,lists.`status`,lists.watched_eps, lists.score,wp_posts.post_title,wp_posts.post_name,wp_terms.slug,wp_postmeta.meta_value from anime_lists
INNER JOIN wp_posts ON (wp_posts.ID = lists.post_id )
INNER JOIN wp_postmeta ON (wp_postmeta.post_id= lists.post_id )
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 lists.id=1
and wp_term_taxonomy.taxonomy = 'category'
and wp_postmeta.meta_key='eps'
group by lists.`post_id`
order by lists.`status`, wp_posts.post_title
As it is, query outputs everything that I need but without these posts that do not have custom field 'eps'. If I remove and wp_postmeta.meta_key='eps' it outputs these posts, but that way I get wrong value in wp_postmeta.meta_value field.
As far as I understand what you want, you can just change your wp_postmeta join to a LEFT JOIN and move the WHERE condition on that table to the join, leaving;
SELECT lists.id, lists.`type`, lists.`status`, lists.watched_eps,
lists.score,wp_posts.post_title,wp_posts.post_name,wp_terms.slug,
wp_postmeta.meta_value
FROM anime_lists
INNER JOIN wp_posts
ON wp_posts.ID = anime_lists.post_id
LEFT JOIN wp_postmeta
ON wp_postmeta.post_id = anime_lists.post_id
AND wp_postmeta.meta_key='eps'
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 lists.id=1
AND wp_term_taxonomy.taxonomy = 'category'
GROUP BY lists.`post_id`
ORDER BY lists.`status`, wp_posts.post_title
First I would like to mention I have limited skills when it comes to MYSQL an JOIN. However this is what I have and what I like to achieve:
I have the default WordPress tables and like to get a result with post_name, title, status and the meta_value from a certain meta key.
This is what I have:
SELECT
wp_posts.ID, wp_posts.post_name, wp_posts.post_title, wp_posts.post_status, wp_postmeta.meta_value
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 )
WHERE (
wp_term_relationships.term_taxonomy_id
IN ( 1, 2, 3 )
)
AND wp_posts.post_type = 'my_post_type'
AND (
wp_posts.post_status
IN (
'my_status_1', 'my_status_2'
)
)
AND wp_postmeta.meta_key = 'my_meta_key'
GROUP BY wp_posts.ID
ORDER BY wp_posts.ID ASC
Everything works as expected when each post has a postmeta of 'my_meta_key'. But if the 'my_meta_key' is missing the post is not in the result.
I guess it' caused by the second INNER JOIN but as mentioned I have no idea what I should it replace it with.
I'm sure it's something simple
Move the AND wp_postmeta.meta_key = 'my_meta_key' to
INNER JOIN
wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id )
Like this and change the INNER for a LEFT
LEFT JOIN
wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id
AND wp_postmeta.meta_key = 'my_meta_key')
If you put your condition in the "Where Clause" The Left join will be "overwritten".
And I will add an advice. Dont use parenthesis when you dont really need it to keep your code easy to read.
The following returns
all records from WP_Posts
only those records with WP_TERM_RELATIONSHIPS
only those records in wp_postmeta which a matching record in wp_posts.
*
SELECT wp_posts.ID, wp_posts.post_name, wp_posts.post_title,
wp_posts.post_status, wp_postmeta.meta_value
FROM wp_posts
LEFT JOIN wp_term_relationships
ON wp_posts.ID = wp_term_relationships.object_id
LEFT JOIN wp_postmeta
ON wp_posts.ID = wp_postmeta.post_id
WHERE wp_term_relationships.term_taxonomy_id IN ( 1, 2, 3 )
AND wp_posts.post_type = 'my_post_type'
AND wp_posts.post_statusIN ('my_status_1', 'my_status_2')
AND (wp_postmeta.meta_key = 'my_meta_key' or wp_postmeta.meta_key is null)
GROUP BY wp_posts.ID
ORDER BY wp_posts.ID ASC
you need the is null otherwise records in wp_posts without wp_postmeta data will be excluded.
Change the INNER JOIN on the wp_postmeta table to a LEFT JOIN:
LEFT JOIN wp_postmeta
ON ( wp_posts.ID = wp_postmeta.post_id )
And move the WHERE filter for the wp_postmeta to the JOIN condition.
So your query will be:
SELECT wp_posts.ID, wp_posts.post_name, wp_posts.post_title, wp_posts.post_status, wp_postmeta.meta_value
FROM wp_posts
INNER JOIN wp_term_relationships
ON ( wp_posts.ID = wp_term_relationships.object_id )
LEFT JOIN wp_postmeta
ON ( wp_posts.ID = wp_postmeta.post_id )
AND wp_postmeta.meta_key = 'my_meta_key'
WHERE wp_term_relationships.term_taxonomy_id IN ( 1, 2, 3 )
AND wp_posts.post_type = 'my_post_type'
AND wp_posts.post_status IN ('my_status_1', 'my_status_2')
GROUP BY wp_posts.ID
ORDER BY wp_posts.ID ASC
The INNER JOIN syntax will only return rows that match in both tables. So if you do not have a matching row, you will not get any result. By changing that to a LEFT JOIN, you will return all rows even if there is not a matching row in the wp_postmeta table. If the row does not exist, then the values from the wp_postmeta table will be null.
I'm using WordPress. I want to get everything from the wp_posts table and two values from the postmeta table.
The "wp_postmeta" has the columns "post_id", "meta_key", and "meta_value".
So far, I'm able to get one of the "meta_value":
SELECT wp_post.*, $wpdb->postmeta.meta_value AS votes
FROM wp_posts
INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id )
WHERE post_type='post'
AND wp_postmeta.meta_key = 'votes'
However, I also want to get another "meta_value" with the same "post_id" but a different "meta_key". How can I extend this query to the "meta_value"?
If you don't want multiple rows per post, you can do this by having multiple joins:
SELECT wp_post.*, metavotes.meta_value AS votes, metaother.meta_value AS other
FROM wp_posts
INNER JOIN wp_postmeta metavotes
ON ( wp_posts.ID = wp_postmeta.post_id AND wp_postmeta.meta_key = 'votes')
INNER JOIN wp_postmeta metaother
ON ( wp_posts.ID = wp_postmeta.post_id AND wp_postmeta.meta_key = 'other')
WHERE post_type='post'
(this assumes there is always exactly 1 row for each piece of metadata in wp_postmeta. I'm not familiar enough with wordpress to know whether this is the case. If metadata is optional, use LEFT OUTER JOIN's instead. If you can have multiple, what kind of output do you want?)
How about adding your additional meta_key to the query with the IN clause. Let's say it's the string value foo that you want to add:
SELECT wp_post.*, $wpdb->postmeta.meta_value AS votes
FROM wp_posts
INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id )
WHERE post_type='post'
AND wp_postmeta.meta_key IN ('votes', 'foo');
Maybe try something like this:
SELECT wp_posts.*, wp_postmeta.meta_value, wp_postmeta.meta_key
FROM wp_posts INNER JOIN wp_postmeta ON(wp_posts.ID = wp_postmeta.post_id)
WHERE wp_posts.post_type='post'
AND wp_postmeta.meta_key IN ('votes', ...)