I need help to finish a SQL Query for a Woocommerce product list. I need this for a wpdatatable sql input.
I searched for a example code and have adapted a found code:
SELECT p.ID, p.post_title, p.post_content, p.post_excerpt, t.name AS product_category, t.term_id AS product_id, tt.term_taxonomy_id AS tt_term_taxonomia, tr.term_taxonomy_id AS tr_term_taxonomia, MAX(CASE WHEN pm1.meta_key = '_price' then pm1.meta_value ELSE NULL END) as price FROM wp_posts p LEFT JOIN wp_postmeta pm1 ON pm1.post_id = p.ID LEFT JOIN wp_term_relationships AS tr ON tr.object_id = p.ID JOIN wp_term_taxonomy AS tt ON tt.taxonomy = 'product_cat' AND tt.term_taxonomy_id = tr.term_taxonomy_id JOIN wp_terms AS t ON t.term_id = tt.term_id WHERE p.post_type in('product', 'product_variation') AND p.post_status = 'publish' GROUP BY p.ID,p.post_title
It works but without product rows for variable products. It shows only the main variation of a product.
Example: product steak: I have 6 different variations of steaks as own products with different prices and also different weight characteristics. With my SQL query I can only see the main product “steak” without variations and variation prices.
Table wp_Posts
id | post_title | post_type | post_parent | post_name | regular_price | -----+--------------------------------+-------------------+-------------+-----------+---------------| 4113 | Steaks | product | 0 | 4119 | Steaks-Lungenbraten Steak 125g | product_variation | 4113 | steaks_4 |6 | 4120 | Steaks-Hüftsteak 200g | product_variation | 4113 | steaks_5 |4,4 | 4121 | Steaks-Flankensteak 600g | product_variation | 4113 | steaks_6 |8,4 |
Table wp_postmeta-
Post_ID |meta_key | meta_value | --------+----------------+----------------------------+--------- 4113 | | 4119 | attribute_pa_steaks | lungenbraten-steak | 4119 | _price. | 6 | 4120 | attribute_pa_steaks | hueftsteak | 4120 | _price. | 4,4 | 4121 | attribute_pa_steaks | flanksteak | 4121 | _price. | 8,4 |
wp_term_relationship
object_id. | term_taxonomy_id. | term_order | ------------+-------------------+------------+ 4113 | 6 | 0 | 4113 | 296 | 0 | 4113 | 297 | 0 | 4113 | 298 | 0 |
wp_term_taxonomy
term_taxonomy_id. | term_id | taxonomy | description. | parent |count | ------------------+----------+-------------+--------------+--------+------+ 296 | 296 | pa_steaks | | 0 | 1. | 297 | 297 | pa_steaks | | 0 | 1. | 298 | 298 | pa_steaks | | 0 | 1. |
wp_terms
term_id | name | slug | term_group | ------------+--------------------+--------------------+------------+ 296 | Flanksteak | flanksteak | 0 | 297 | Hüftsteakk | hueftsteak | 0 | 298 | Lungenbraten Steak | Lungenbraten-steak | 0 |
Advertisement
Answer
Your query is invalid, as the select list doesn’t match the GROUP BY
. Even if you DBMS is flawed and doesn’t raise an error, I don’t recommend using such a query. It’s results may be arbitrary (as is the case in MySQL for instance). Write a query that leaves no doubt as to what data you really want to select.
As you want just one value from the key/value table wp_postmeta
, you don’t need aggregation:
SELECT p.id, p.post_title, p.post_content, p.post_excerpt, t.name AS product_category, t.term_id AS product_id, tt.term_taxonomy_id AS tt_term_taxonomia, tr.term_taxonomy_id AS tr_term_taxonomia, pm1.meta_value AS price FROM wp_posts p LEFT JOIN wp_postmeta pm1 ON pm1.post_id = p.ID AND pm1.meta_key = '_price' JOIN wp_term_relationships AS tr ON tr.object_id = p.ID JOIN wp_term_taxonomy AS tt ON tt.taxonomy = 'product_cat' AND tt.term_taxonomy_id = tr.term_taxonomy_id JOIN wp_terms AS t ON t.term_id = tt.term_id WHERE p.post_type in('product', 'product_variation') AND p.post_status = 'publish' ORDER BY CASE WHEN p.post_parent = 0 THEN id else post_parent END, CASE WHEN p.post_parent = 0 THEN 1 else 2 END;