Wordpress:Sql选择所有相关元的帖子

时间:2017-06-18 14:40:42

标签: php mysql wordpress

我需要获得一系列包含所有相关元数据的帖子。 所以看起来应该是这样的:

post
  postfields from post table : [
                               'title' =>...
                               'content'=>...
                               etc....
                               ]
  array of values from meta : [
                               [],
                               []
                              ],
 post
   postfields from post table : [
                               'title' =>...
                               'content'=>...
                               etc....
                               ]
   array of values from meta : [
                               [],
                               []
                              ]

我正在尝试做什么:

SELECT
    *
FROM wp_posts
    INNER JOIN wp_postmeta
    ON wp_posts.ID = wp_postmeta.post_id
    WHERE wp_posts.post_type = 'page'
    GROUP BY wp_posts.ID

但它失败了。

#1055 - Expression #24 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'somedbname.wp_postmeta.meta_id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

如何在一个查询中获取包含所有相关元数据的所有帖子?

1 个答案:

答案 0 :(得分:1)

这两个表有几点需要注意。

  1. Posts和Post Meta有一对多的关系。因此,通过使用GROUP BY wp_posts.ID,您可以将结果限制为具有第一个可关联的帖子元记录的单个帖子(以及任何其他相关的帖子元素获胜并且不会显示)。
  2. 使用INNER JOIN wp_postmeta,查询不会返回发布元数据的任何帖子。
  3. 您可以使用的一种设计模式是执行查询而不使用 GROUP BY wp_posts.ID(这将导致单个帖子有多行,因为每行将包含相同的帖子ID但不同的帖子meta)并在PHP中重构您的数组。与进行多个查询相比,PHP中的这种循环相当高效。如果需要,您还可以将结果缓存到transient

    为了澄清一个例子,你应该能够像这样执行你的查询:

    global $wpdb;
    $results = $wpdb->get_results( "SELECT * FROM wp_posts LEFT JOIN wp_postmeta ON wp_posts.ID = wp_postmeta.post_id WHERE wp_posts.post_type = 'page' ORDER BY wp_posts.ID" );
    
    if ( ! empty( $results ) ) {
        $previous_id = 0;
        $structured_results = array();
        foreach ( $results as $post ) {
            if ( $previous_id !== $post->ID ) {
                $structured_results[ $post->ID ] = array(
                    'ID' => $post->ID,
                    'post_author' => $post->post_author,
                    'post_date' => $post->post_date,
                    'post_title' => $post->post_title,
                    // etc for all other columns in wp_posts
                    'post_meta' => array(
                        $post->meta_id => array(
                            'meta_key' => $post->meta_key,
                            'meta_value' => $post->meta_value,
                        ),
                    ),
                );
            } else {
                $structured_results[ $post->ID ]['post_meta'][ $post->meta_id ] = array(
                    'meta_key' => $post->meta_key,
                    'meta_value' => $post->meta_value,
                );
    
            }
            $previous_id = $post->ID;
        }
    }
    

    这将为您提供名为structured_results的单个结果数组。数组的每个元素都是一个帖子(它的关键是帖子ID)。每个元素都将包含wp_posts中的所有列。此外,每个元素都有一个名为post_meta的键,它是所有后元记录的数组。

    几点说明:

    • 这是一个LEFT JOIN,因此它将包含没有帖子元的帖子(如果您只想要带有元的帖子,请使用INNER JOIN。)
    • 我没有从wp_posts填写上面代码中的所有列,因此您可以添加其他列(例如post_content等)。