同一表同一列输出不同值及两行数据合并为一行两列的技术问题
看起来你在处理WordPress的wp_posts和wp_postmeta表关联时,遇到了两个具体的展示需求实现问题,我来帮你梳理下正确的SQL写法和对应的PHP展示逻辑:
先修正你当前SQL的逻辑问题
你现在的WHERE子句里AND和OR的优先级没有处理好,会导致筛选逻辑出错——当前写法会把所有wp_postmeta.meta_key='_stock'的记录都拉出来,不管对应的post是不是product类型。正确的做法是把OR的条件用括号包裹起来,不过这只是基础,我们针对你的两个需求分别调整SQL:
需求1:同一列输出不同元数据值(每个产品的促销价、库存各占一行)
如果要让每个产品的_sale_price和_stock作为单独的行输出,同一列显示不同的值,只需要调整WHERE子句的逻辑,同时明确要查询的字段:
SELECT wp_posts.ID, wp_posts.post_title, wp_postmeta.meta_key, wp_postmeta.meta_value FROM wp_posts LEFT JOIN wp_postmeta ON wp_posts.ID = wp_postmeta.post_id WHERE wp_posts.post_type='product' AND (wp_postmeta.meta_key='_sale_price' OR wp_postmeta.meta_key='_stock') ORDER BY wp_posts.ID, wp_postmeta.meta_key
这样查询后,每个产品会生成两行数据:一行对应促销价,一行对应库存,meta_value列就会显示不同的内容。对应的PHP展示可以保留循环,同时增加meta_key列来区分当前值的类型:
foreach($sth as $row) { ?> <tr> <td><?php echo $row["ID"]; ?></td> <td><?php echo $row["post_title"]; ?></td> <td><?php echo ucwords(str_replace('_', ' ', $row["meta_key"])); ?></td> <td><?php echo $row["meta_value"]; ?></td> </tr> <?php } ?>
这里用ucwords(str_replace('_', ' ', $row["meta_key"]))把_sale_price转换成更友好的Sale Price显示。
需求2:把两个元数据值放到同一行的不同列(一行展示产品+促销价+库存)
这时候需要两次关联wp_postmeta表,给每个关联取不同的别名,分别对应_sale_price和_stock,这样就能把两个值拆成独立的列:
SELECT wp_posts.ID, wp_posts.post_title, sale_meta.meta_value AS sale_price, stock_meta.meta_value AS stock FROM wp_posts LEFT JOIN wp_postmeta AS sale_meta ON wp_posts.ID = sale_meta.post_id AND sale_meta.meta_key='_sale_price' LEFT JOIN wp_postmeta AS stock_meta ON wp_posts.ID = stock_meta.post_id AND stock_meta.meta_key='_stock' WHERE wp_posts.post_type='product' ORDER BY wp_posts.ID
这里用sale_meta和stock_meta作为表别名,分别关联对应的元数据键,查询结果中每个产品只会占一行,sale_price和stock是独立的列。对应的PHP展示可以直接输出这两个列,同时处理可能的空值情况:
foreach($sth as $row) { ?> <tr> <td><?php echo $row["ID"]; ?></td> <td><?php echo $row["post_title"]; ?></td> <td><?php echo $row["sale_price"] ?? '无促销价'; ?></td> <td><?php echo $row["stock"] ?? '无库存数据'; ?></td> </tr> <?php } ?>
用??运算符可以优雅处理元数据不存在的情况,避免页面显示空内容。
内容的提问来源于stack exchange,提问作者svedrine

