首页 > 解决方案 > MySQL 动态查询使用来自查询本身的信息

问题描述

我有一个查询要从 WooCommerce 获取产品数据。产品具有变体(即属性),并且与基础产品相结合的每个属性组合都是其自己的 SKU。对于每个 SKU,数据都使用具有关联值的相当通用的键(例如 _sku、_price)写入 post_meta 表。例外是属性描述字段,奇怪的是,它的键是基于基本产品名称本身。这似乎没有必要,因为我们已经知道它指的是哪个基础产品。尽管如此,它就是这样完成的。

在下面的示例中,基本产品名称是“Ford RAM 1500”。我只是为测试做一个单一的变体,属性是“拖车”,它指定了卡车的拖车类型。拖车类型可以是“无拖车”、“hitch-2in”、“hitch-2.5in”、“hitch-3in”。然后它在 Post_Meta 表中创建一个名为“attribute_ford_ram_1500”的键,并为元值分配一个描述,例如“hitch-2in $25,269”——变体项目和包括该变体的总价格。

到目前为止,这是我的查询:

SELECT * FROM
(
SELECT p.ID,
p.post_title 'name',  -- Ford RAM 1500
p.post_content 'description',
GROUP_CONCAT(cat.name SEPARATOR ' | ') 'Category',
MAX(CASE WHEN meta.meta_key = '_sku' THEN meta.meta_value END) 'SKU',
MAX(CASE WHEN meta.meta_key = 'attribute_trailer' THEN meta.meta_value END) 'Trailer',  -- Trailer type added to product, or none
MAX(CASE WHEN meta.meta_key = 'attribute_ford_ram_1500' THEN meta.meta_value END) 'Var_Description',  -- Ford RAM 1500 is from the p.post_title (name) field above
MAX(CASE WHEN meta.meta_key = '_price' THEN meta.meta_value END) 'Price',
MAX(CASE WHEN meta.meta_key = '_weight' THEN meta.meta_value END) 'Weight',
MAX(CASE WHEN meta.meta_key = '_stock' THEN meta.meta_value END) 'Stock'
FROM wp_posts AS p
JOIN wp_postmeta AS meta ON p.ID = meta.post_ID
LEFT JOIN
(
SELECT pp.id,
GROUP_CONCAT(t.name SEPARATOR ' > ') AS name
FROM wp_posts AS pp
JOIN wp_term_relationships tr ON pp.id = tr.object_id
JOIN wp_term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
JOIN wp_terms t ON tt.term_id = t.term_id
|| tt.parent = t.term_id
WHERE tt.taxonomy = 'product_cat'
GROUP BY pp.id, tt.term_id
) cat ON p.id = cat.id
WHERE (p.post_type = 'product' OR p.post_type = 'product_variation')
AND meta.meta_key IN ('_sku', '_price', '_weight', '_stock','attribute_foundation','attribute_ford_ram_1500')  -- Would need to dynamically change the last attribute based on the p.post_title (name) field
AND meta.meta_value is not null
GROUP BY p.ID
) d
WHERE d.SKU IS NOT NULL

这很好用 - 对于一种基础产品。但是假设还有福特 RAM 2500 产品。对于它的变体,不会有 meta.meta_key = 'attributes_ford_ram_1500'; 相反,它将是 meta.meta_key = 'attributes_ford_ram_2500'。我假设我需要做一些更有活力的事情。所以我的问题是,如何让我的查询根据该结果行中的 post_title(名称)找到正确的 meta_key 名称?

标签: mysqlwoocommerce

解决方案


您应该能够使用表达式而不是硬编码来形成 meta_key:

...
MAX(CASE WHEN meta.meta_key = CONCAT('attribute_', 
    REPLACE(p.post_title, ' ', '_')) 
  THEN meta.meta_value END) AS `Var_Description`,
...

请记住,您必须使用p.post_title,因为您不能在定义别名的同一选择列表中引用别名。


推荐阅读