MySQL如何选择带有META_VALUES和所有相关类别的帖子列表?

时间:2016-01-12 作者:Victoria

我试图生成一个帖子列表,并显示一个报告,其中既显示了每个帖子的一些meta\\u值,也显示了每个帖子所附加的所有类别的列表。

我正在使用漂亮的导出和报告模块格式化查询结果,我试图提取的数据是Woocommerce产品的列表。

我做到了:

SELECT wp_posts.ID, wp_posts.post_title AS Product, m2.meta_value AS _retail_price,  m4.meta_value AS _stock
FROM wp_posts


LEFT JOIN wp_postmeta AS m2 ON m2.post_id = wp_posts.ID AND m2.meta_key = \'_price\'
LEFT JOIN wp_postmeta AS m4 ON m4.post_id = wp_posts.ID AND m4.meta_key = \'_stock\'
WHERE wp_posts.post_type IN (\'product\', \'product_variation\')  
AND  wp_posts.post_status = \'publish\'
ORDER BY wp_posts.ID ASC
这样就可以了,我得到一个包含相关元值的帖子(产品)列表。

但我现在想添加一个类别列表,每个帖子都列在其中,最好每个类别都有一列。但每个帖子都有多个类别,我很困惑如何为每个帖子抽取类别。

我做到了:

SELECT wp_posts.ID AS ProdId, wp_posts.post_title AS Product, m1.meta_value AS _retail_price,  m2.meta_value AS _stock, wp_term_relationships.*, wp_terms.* 
FROM wp_posts, wp_term_relationships, wp_terms


LEFT JOIN wp_postmeta AS m1 ON m1.post_id = wp_posts.ID AND m1.meta_key = \'_price\'
LEFT JOIN wp_postmeta AS m2 ON m2.post_id = wp_posts.ID AND m2.meta_key = \'_stock\'

LEFT JOIN wp_posts posts2 ON wp_term_relationships.object_id = wp_posts.ID
LEFT JOIN wp_term_taxonomy ON wp_term_taxonomy.term_taxonomy_id = wp_term_relationships.term_taxonomy_id
LEFT JOIN wp_terms terms2 ON wp_terms.term_id = wp_term_relationships.term_taxonomy_id


WHERE wp_posts.post_type IN (\'product\', \'product_variation\')  
AND  wp_posts.post_status = \'publish\' AND taxonomy = \'product_cat\'
ORDER BY wp_posts.ID ASC
但这给了我一个#1054-未知列“wp\\U帖子”。我加入了on子句,我想我的连接有点纠结:-(

3 个回复
最合适的回答,由SO网友:bonger 整理而成

在SQL方面,您只需要连接到wp\\u posts表一次。连接到terms stuff将提供多行,因此可能最容易的方法是将这些行分组,然后使用group\\u CONCAT()将这些术语平铺成逗号分隔的字符串(updated to use LEFT joins):

global $wpdb;
$sql = $wpdb->prepare(
    \'SELECT p.ID, p.post_title AS Product, pm1.meta_value AS _retail_price, pm2.meta_value AS _stock\'
    . \', GROUP_CONCAT(t.name ORDER BY t.name) AS Categories\'
    . \' FROM \' . $wpdb->posts . \' p\'
    . \' LEFT JOIN \' . $wpdb->postmeta . \' pm1 ON pm1.post_id = p.ID AND pm1.meta_key = %s\'
    . \' LEFT JOIN \' . $wpdb->postmeta . \' pm2 ON pm2.post_id = p.ID AND pm2.meta_key = %s\'
    . \' LEFT JOIN \' . $wpdb->term_relationships . \' AS tr ON tr.object_id = p.ID\'
    . \' LEFT JOIN \' . $wpdb->term_taxonomy . \' AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id AND tt.taxonomy = %s\'
    . \' LEFT JOIN \' . $wpdb->terms . \' AS t ON tt.term_id = t.term_id\'
    . \' WHERE p.post_type in (%s, %s) AND p.post_status = %s\'
    . \' GROUP BY p.ID\'
    . \' ORDER BY p.ID ASC\'
    , \'_price\', \'_stock\', \'product_cat\', \'product\', \'product_variation\', \'publish\'
);
$ret = $wpdb->get_results( $sql );

SO网友:Sterling Hamilton

cracks knuckles

好吧,所以第一件事就是第一件事。

使用WordPress数据库工作请阅读以下内容:https://codex.wordpress.org/Class_Reference/wpdbwp_users 相反,请执行以下操作:

$users = $wpdb->get_results( "SELECT FROM $wpdb->users" );
如果您更改了数据库前缀,这将很有帮助。

在WPDB之外执行此操作,您的伪代码可以如下所示:

获取帖子>获取每个帖子类别>获取每个帖子名为X的元字段。

让我们把所有的东西都存储在一个叫做。。。$all_the_things = array();

获取帖子:

<?php
    $arguments = array(
        \'posts_per_page\'   => -1, // This is a bad idea if you run this on trafficked pages. 
        \'post_type\'        =>  array(\'product\', \'product_variation\'),
        \'post_status\'      => \'publish\'
    );
    $query = WP_Query( $arguments );
?>
现在需要循环:

<?php
    while( $query->have_posts() ) {
        $categories = get_the_category();
        $price = get_post_meta( get_the_ID(), \'_price\' ); ?>
        $stock = get_post_meta( get_the_ID(), \'_stock\' ); ?>
        $all_the_things[get_the_ID()] = array($categories, $price, $stock);
    }
?>
现在如果你想。。。我可以在SQL中做到这一点,但这并不理想。您不能指望数据库结构保持完全相同,也不能指望应该对数据执行的过滤器等。事情可能会变得复杂。

让我知道这是怎么回事,如果需要,我可以提供更多细节。

SO网友:Nathan Powell

您可以使用get_posts() 作用我试图理解您的SQL查询,并以使用本机WP功能的方式定义它,但可能遗漏了一些细节。I have no clue if this is where you are going, or if this works, 但是WordPress应该会让你更容易。Explore this page for more info. 希望这能让你更轻松地接近目标!理想情况下,这会得到您需要在列中放置的所有可能的帖子,并且您可以对$posts 根据需要。

// Argument array for get_posts
$args = array(
    \'post_type\' => array(
        \'product\',
        \'product_variation\',
    ),
    \'meta_query\' => array(
        \'relation\' => \'OR\',
        array(\'key\' => \'_price\'),
        array(\'key\' => \'_stock\'),
    ),
    \'tax_query\' => array(
        array(
            \'taxonomy\' => \'product_cat\',
        )
    )
);

// The posts delivered
$posts = get_posts( $args );