I have a problem when doing a SQL query in WordPress, I would like to have each Post ID in a single row with the meta_key columns, but I get several uneven records.
SELECT P.ID,
IF(PM.meta_key = 'nombrem', PM.meta_value, NULL) AS nombrem,
IF(PM.meta_key = 'generom', PM.meta_value, NULL) AS generom,
IF(PM.meta_key = 'tiempom', PM.meta_value, NULL) AS tiempom,
IF(PM.meta_key = 'urlm', PM.meta_value, NULL) AS urlm,
IF(PM.meta_key = 'imagenm', PM.meta_value, NULL) AS imagenm
FROM K1nG_posts AS P
LEFT JOIN K1nG_postmeta AS PM ON ( P.ID = PM.post_id )
WHERE P.post_type = 'post'
AND (P.post_status = 'publish' OR P.post_status = 'private') ORDER BY P.post_date DESC
By placing the above code I get the following in phpmyadmin, I want a single post ID to have each meta_value value in a non-diagonal horizontal column as shown.
You seeem to be looking for conditional aggregation. For this, you would need to add a GROUP BY clause and surround your conditional expressions with an aggregate function:
SELECT P.ID,
MAX(CASE WHEN PM.meta_key = 'nombrem' THEN PM.meta_value END) AS nombrem,
MAX(CASE WHEN PM.meta_key = 'generom' THEN PM.meta_value END) AS generom,
MAX(CASE WHEN PM.meta_key = 'tiempom' THEN PM.meta_value END) AS tiempom,
MAX(CASE WHEN PM.meta_key = 'urlm' THEN PM.meta_value END) AS urlm,
MAX(CASE WHEN PM.meta_key = 'imagenm' THEN PM.meta_value END) AS imagenm
FROM
K1nG_posts AS P
LEFT JOIN K1nG_postmeta AS PM ON P.ID = PM.post_id
WHERE
P.post_type = 'post'
AND (P.post_status = 'publish' OR P.post_status = 'private')
GROUP BY P.ID, P.post_date
ORDER BY P.post_date DESC
Group the data by P.id and max the ifs out
like
SELECT P.ID,
MAX(IF(PM.meta_key = 'nombrem', PM.meta_value, NULL)) AS nombrem,
MAX(IF(PM.meta_key = 'generom', PM.meta_value, NULL)) AS generom,
MAX(IF(PM.meta_key = 'tiempom', PM.meta_value, NULL)) AS tiempom,
MAX(IF(PM.meta_key = 'urlm', PM.meta_value, NULL)) AS urlm,
MAX(IF(PM.meta_key = 'imagenm', PM.meta_value, NULL)) AS imagenm
FROM K1nG_posts AS P
LEFT JOIN K1nG_postmeta AS PM ON ( P.ID = PM.post_id )
WHERE P.post_type = 'post'
AND (P.post_status = 'publish' OR P.post_status = 'private') ORDER BY P.post_date DESC
GROUP BY P.ID;
Related
I have a problem trying to get data from a specific meta_value in WordPress, that is, when I do a "WHERE AND (PM.meta_key= 'webm' and PM.meta_value= 'Chaturbate')" in the sql query. When I don't use where and get all the data it usually looks like this:
SELECT P.ID,
MAX(CASE WHEN PM.meta_key = 'nombrem' THEN PM.meta_value END) AS nombrem,
MAX(CASE WHEN PM.meta_key = 'generom' THEN PM.meta_value END) AS generom,
MAX(CASE WHEN PM.meta_key = 'tiempom' THEN PM.meta_value END) AS tiempom,
MAX(CASE WHEN PM.meta_key = 'urlm' THEN PM.meta_value END) AS urlm,
MAX(CASE WHEN PM.meta_key = 'imagenm' THEN PM.meta_value END) AS imagenm
FROM
K1nG_posts AS P
LEFT JOIN K1nG_postmeta AS PM ON P.ID = PM.post_id
WHERE
P.post_type = 'post'
AND (P.post_status = 'publish' OR P.post_status = 'private')
GROUP BY P.ID, P.post_date
But when I use the "WHERE AND (PM.meta_key= 'webm' and PM.meta_value= 'Chaturbate')" in a meta_value of a respective meta_key called "webm", I get the matching records but without the "select" information, that is, null, as can be seen in the image:
SELECT P.ID,
MAX(CASE WHEN PM.meta_key = 'nombrem' THEN PM.meta_value END) AS nombrem,
MAX(CASE WHEN PM.meta_key = 'generom' THEN PM.meta_value END) AS generom,
MAX(CASE WHEN PM.meta_key = 'tiempom' THEN PM.meta_value END) AS tiempom,
MAX(CASE WHEN PM.meta_key = 'urlm' THEN PM.meta_value END) AS urlm,
MAX(CASE WHEN PM.meta_key = 'imagenm' THEN PM.meta_value END) AS imagenm
FROM
K1nG_posts AS P
LEFT JOIN K1nG_postmeta AS PM ON P.ID = PM.post_id
WHERE
P.post_type = 'post'
AND (P.post_status = 'publish' OR P.post_status = 'private')
AND (PM.meta_key= 'webm' and PM.meta_value= 'Chaturbate')
GROUP BY P.ID, P.post_date
try to use this code
WHERE
P.post_type = 'post'
AND P.post_status = 'publish' OR P.post_type = 'post' AND P.post_status = 'private'
this basically takes
P.post_type = 'post' AND P.post_status
as A
and
P.post_type = 'post' AND P.post_status = 'private'
as B
so it is
A or B
I have a problem when ordering an epoch field, it does not return the results ordered by date. Then I show you my code.
SELECT P.ID,
MAX(CASE WHEN PM.meta_key = 'nombrem' THEN PM.meta_value END) AS nombrem,
MAX(CASE WHEN PM.meta_key = 'generom' THEN PM.meta_value END) AS generom,
MAX(CASE WHEN PM.meta_key = 'tiempom' THEN PM.meta_value END) AS tiempom,
MAX(CASE WHEN PM.meta_key = 'urlm' THEN PM.meta_value END) AS urlm,
MAX(CASE WHEN PM.meta_key = 'imagenm' THEN PM.meta_value END) AS imagenm
FROM
K1nG_posts AS P
LEFT JOIN K1nG_postmeta AS PM ON P.ID = PM.post_id
WHERE
P.post_type = 'post'
AND (P.post_status = 'publish' OR P.post_status = 'private')
GROUP BY P.ID, P.post_date ORDER BY FROM_UNIXTIME('tiempom')
The format of the "tiempom" field is as follows:
1570480237
I get the following error.
Warning: # 1292 Wrong truncated DECIMAL value: 'tiempom'
you can either
GROUP BY P.ID, P.post_date ORDER BY FROM_UNIXTIME(tiempom)
or use backticks `
GROUP BY P.ID, P.post_date ORDER BY FROM_UNIXTIME(`tiempom`)
Because mysql thinks you want to convert the string 'tiempom' into a datetime .
I use this query sql to retrieve all products without image
SELECT id
FROM `wp_posts`
WHERE id NOT IN (SELECT post_id FROM `wp_postmeta` WHERE `meta_key` =
'_thumbnail_id')
AND `post_type` = 'product'
AND `post_status` = 'publish'
Now I would retrieve all products without image and stock status in stock, is there a way to do it?
The following SQL Query will allow you to retrieve products without image that are "In stock":
SELECT ID
FROM wp_posts p
INNER JOIN wp_postmeta pm ON p.ID = pm.post_id
WHERE ID NOT IN (SELECT post_id FROM wp_postmeta WHERE meta_key = '_thumbnail_id')
AND p.post_type = 'product'
AND p.post_status = 'publish'
AND pm.meta_key = '_stock_status'
AND pm.meta_value = 'instock'
Or you can query it using WPDB Class through php like:
global $wpdb;
$product_ids = $wpdb->get_col( "
SELECT ID
FROM {$wpdb->prefix}posts p
INNER JOIN {$wpdb->prefix}postmeta pm ON p.ID = pm.post_id
WHERE ID NOT IN (SELECT post_id FROM {$wpdb->prefix}postmeta WHERE meta_key = '_thumbnail_id')
AND p.post_type = 'product'
AND p.post_status = 'publish'
AND pm.meta_key = '_stock_status'
AND pm.meta_value = 'instock'
");
// Raw output
print_r($product_ids);
here's my code :
SELECT p.ID, p.post_title,
MAX(IF(pm.meta_key = 'featured_image', pm.meta_value, NULL)) AS event_imgID
FROM wpgp_posts AS p
LEFT JOIN wpgp_postmeta AS pm on pm.post_id = p.ID
WHERE p.post_type = 'product' and p.post_status = 'publish'
GROUP BY p.ID
event_imgID retrieve the ID from postmeta but the img url is stored in the wpgp_posts in the guid column
How to achieve this ?
You can join in the table to get more information about the image:
SELECT . . .
FROM (SELECT p.ID, p.post_title,
MAX(CASE WHEN pm.meta_key = 'featured_image' THEN pm.meta_value END) AS event_imgID
FROM wpgp_posts p LEFT JOIN
wpgp_postmeta pm
ON pm.post_id = p.ID
WHERE p.post_type = 'product' and p.post_status = 'publish'
GROUP BY p.ID
) pi LEFT JOIN
wpgp_posts wp
ON pi.event_imgID = wp.guid
I finally found the way to do it. I had to search thumbnail_id instead of guid :
SELECT
p1.ID, p1.post_title,
MAX(IF(pm.meta_key = 'listing_event_date', pm.meta_value, NULL)) AS event_date,
wm2.meta_value as event_img
FROM
wpgp_posts p1
LEFT JOIN wpgp_postmeta AS pm on (pm.post_id = p1.ID)
LEFT JOIN
wpgp_postmeta wm1
ON (
wm1.post_id = p1.id
AND wm1.meta_value IS NOT NULL
AND wm1.meta_key = '_thumbnail_id'
)
LEFT JOIN
wpgp_postmeta wm2
ON (
wm1.meta_value = wm2.post_id
AND wm2.meta_key = '_wp_attached_file'
AND wm2.meta_value IS NOT NULL
)
WHERE
p1.post_status='publish'
AND p1.post_type='product'
GROUP BY p1.ID, wm2.meta_id
ORDER BY
event_date ASC
Thanks
I have term parent called 'product_parent' that has three childs terms :
child_term_1 (id=2) (5 posts)
child_term_2 (id=3) (3 posts)
child_term_3 (id=4) (10 posts)
each post has **meta_key price ** (string) and i have to filter posts by price:
0 to 50, 50 to 100 and 100 +
this query works well (i can get 15 products):
SELECT DISTINCT p.ID FROM wp_posts as p
LEFT JOIN wp_postmeta as p ON price.post_id = p.ID
LEFT JOIN wp_relationships as t ON t.object_id = p.ID
WHERE p.post_type = 'product' AND post_status = 'publish'
AND t.term_taxonomy_id IN ('2', '3', '4')
AND p.meta_key = 'price'
AND p.meta_value LIKE '%50-100%'
OR p.meta_value LIKE '%100+%'
GROUP BY p.ID
but if i add one filter :
SELECT DISTINCT p.ID FROM wp_posts as p
LEFT JOIN wp_postmeta as p ON price.post_id = p.ID
LEFT JOIN wp_relationships as t ON t.object_id = p.ID
WHERE p.post_type = 'product' AND post_status = 'publish'
AND t.term_taxonomy_id IN ('2', '3', '4')
AND p.meta_key = 'price'
AND p.meta_value LIKE '%0-50%'
OR p.meta_value LIKE '%50-100%'
OR p.meta_value LIKE '%100+%'
GROUP BY p.ID
This returns "many posts" that not in term_taxonomy_id specified.
Someone could clarify me please? i don't want to use Wp_Query(), i just want to use sql.
Thanks for your help.
you use the same alias
then duplicate alias
try:
SELECT DISTINCT p.ID FROM wp_posts as p
LEFT JOIN wp_postmeta as pm ON pm.post_id = p.ID
LEFT JOIN wp_relationships as r ON r.object_id = p.ID
WHERE p.post_type = 'product' AND p.post_status = 'publish'
AND r.term_taxonomy_id IN ('2', '3', '4')
AND pm.meta_key = 'price'
AND pm.meta_value LIKE '%0-50%'
OR pm.meta_value LIKE '%50-100%'
OR pm.meta_value LIKE '%100+%'
GROUP BY p.ID