4

これは私の現在のクエリです:

query_posts(array_merge(array('tag' => $pagetag,'meta_key'=>priority,'orderby' =>meta_value, 'order' =>'ASC','paged' => get_query_var('paged'))));

私の問題は、「優先度」が NULL ではないことを意味する「meta_key」の値を持つ投稿のみがクエリに表示されることです。このクエリを改善するにはどうすればよいですか?

前もって感謝します!

4

4 に答える 4

6

問題は、条件で言及するとすぐにWordPress がテーブルに を追加するINNER JOINことです。この問題を回避する方法の 1 つは、句に次のようなフィルターを追加することです。wp_postmetameta_keyorder by

function so_orderby_priority($original_orderby_statement) {
    global $wpdb;

    return "(SELECT $wpdb->postmeta.meta_value
               FROM $wpdb->postmeta
              WHERE $wpdb->posts.ID = $wpdb->postmeta.post_id
                AND $wpdb->postmeta.meta_key = 'priority') ASC";
}

add_filter('posts_orderby', 'so_orderby_priority');

query_posts(
    array(
        'tag' => $pagetag,
        'paged' => get_query_var('paged')
    )
);

remove_filter('posts_orderby', 'so_orderby_priority');

MySQL は NULL を最初にソートすることに注意してください。最後にソートする場合は、次のようにしてください (すべての優先順位が ZZZZZ アルファベット順で前にあると仮定します)。

function so_orderby_priority($original_orderby_statement) {
    global $wpdb;

    return "IFNULL(
               (SELECT $wpdb->postmeta.meta_value
                  FROM $wpdb->postmeta
                 WHERE $wpdb->posts.ID = $wpdb->postmeta.post_id
                   AND $wpdb->postmeta.meta_key = 'priority'),
                'ZZZZZ') ASC";
}

編集

もう少し説明がありますが、これは SQL をある程度理解していることを前提としています。

オリジナルquery_postsでは、データベースに対して次のクエリが実行されました。

SELECT wp_posts.*
FROM   wp_posts
       INNER JOIN wp_term_relationships ON ( wp_posts.id = wp_term_relationships.object_id )
       INNER JOIN wp_postmeta ON ( wp_posts.id = wp_postmeta.post_id )
WHERE  1 = 1
       AND ( wp_term_relationships.term_taxonomy_id IN ( 3 ) )
       AND wp_posts.post_type = 'post'
       AND ( wp_posts.post_status = 'publish'
              OR wp_posts.post_status = 'private' )
       AND ( wp_postmeta.meta_key = 'priority' )
GROUP  BY wp_posts.id
ORDER  BY wp_postmeta.meta_value ASC
LIMIT  0, 10; 

それINNER JOIN wp_postmetaが、結果から優先度のない投稿を削除した理由です。

meta_*関連する条件を から削除するquery_posts:

query_posts(
    array(
        'tag' => $pagetag,
        'paged' => get_query_var('paged')
    )
);

その問題は解決しましたが、ソート順はまだ間違っています。新しい SQL は

SELECT wp_posts.*
FROM   wp_posts
       INNER JOIN wp_term_relationships ON ( wp_posts.id = wp_term_relationships.object_id )
WHERE  1 = 1
       AND ( wp_term_relationships.term_taxonomy_id IN ( 3 ) )
       AND wp_posts.post_type = 'post'
       AND ( wp_posts.post_status = 'publish'
              OR wp_posts.post_status = 'private' )
GROUP  BY wp_posts.id
ORDER  BY wp_posts.post_date DESC
LIMIT  0, 10; 

フィルターを使用すると、句posts_orderbyを変更できます: gets フィルターが返すものに置き換えられます。最終的な SQL は次のようになります。ORDER BYwp_posts.post_date DESC

SELECT wp_posts.*
FROM   wp_posts
       INNER JOIN wp_term_relationships ON ( wp_posts.id = wp_term_relationships.object_id )
WHERE  1 = 1
       AND ( wp_term_relationships.term_taxonomy_id IN ( 3 ) )
       AND wp_posts.post_type = 'post'
       AND ( wp_posts.post_status = 'publish'
              OR wp_posts.post_status = 'private' )
GROUP  BY wp_posts.id
ORDER  BY (SELECT wp_postmeta.meta_value
           FROM   wp_postmeta
           WHERE  wp_posts.id = wp_postmeta.post_id
                  AND wp_postmeta.meta_key = 'priority') ASC
LIMIT  0, 10 

それはあなたが求めていることをします。

于 2012-07-03T17:24:27.537 に答える
1

追加したカスタム列の users.php ページで同様のタスクを実行する必要があり、Hobo から変更した次のコードを使用しました。

add_action('pre_user_query', 'qd_users_column_orderby');

function qd_users_column_orderby($userquery){
  if('my_last_login'==$userquery->query_vars['orderby']) { //check if my cusomt meta_key is the column being sorted

    global $wpdb;

    $userquery->query_orderby = " ORDER BY(SELECT $wpdb->usermeta.meta_value
        FROM $wpdb->usermeta
        WHERE $wpdb->users.ID = $wpdb->usermeta.user_id
        AND $wpdb->usermeta.meta_key = 'my_last_login') ".($userquery->query_vars["order"] == "ASC" ? "asc " : "desc ")." , wp_users.user_login ".($userquery->query_vars["order"] == "ASC" ? "asc " : "desc ");
  }
}

うまくいけば、これはこの情報を必要としている誰かに役立ちます.

全体を把握するために、私の個々のタスクを完了するために必要な残りのコードを以下に示します。

add_filter('manage_users_columns', 'qd_add_user_login_column');

function qd_add_user_login_column($columns) {
  $columns['my_last_login'] = 'Last Logged In';
  return $columns;
}

add_action('manage_users_custom_column',  'qd_show_user_login_column_content', 10, 3);

function qd_show_user_login_column_content($value, $column_name, $user_id) {
  $user = get_userdata( $user_id );
  if ( 'my_last_login' == $column_name ){
    $lastLogin = get_the_author_meta('my_last_login', $user_id);
    if(!$lastLogin){
      return "Never";
    }else{
      date_default_timezone_set(get_option('timezone_string'));
      return date('m/d/y g:ia', $lastLogin); 
    }
  }
  return $value;
}

add_filter( 'manage_users_sortable_columns', 'qd_users_table_sorting' );

function qd_users_table_sorting( $columns ) {
  $columns['my_last_login'] = 'my_last_login';
  return $columns;
}
于 2014-02-14T15:48:00.430 に答える
-1

これを行う最も簡単な方法は、アクションを使用してカスタム フィールドを挿入することです。これsave_post により、公開されたすべての投稿に独自meta_keyのデフォルト値が設定されます。

post_metaメタを持たないすべての投稿に追加するには、MySQL クエリを使用します。それでおしまい。

あなた/誰かがこれについてコードの助けが必要な場合は、返信してください:)

アップデート

Timusan が尋ねたように、メタキー名を変更した後、このコードを functions.php ファイルに追加します。

add_action('save_post', 'sidati_post_views_metakey');

function sidati_post_views_metakey ($post_id){

    /*
    * $post_id = is the post ID
    * 'sidati_post_views' => is your metakey name (sidati is prefix always nice to add your prefix)
    * 0 => the inital value
    * true => (bool) add true if you want this metakkey become unique
    */

    add_post_meta($post_id, 'sidati_post_views', 0, true);

}


// THIS ACTION MUST RUN ONLY ONE TIME
add_action('init', 'sidati_allposts_must_have_this');

function sidati_allposts_must_have_this(){

    /* Call the WordPress DataBase class */
    global $wpdb; 

    /* This Query will get us all the posts and pages without "sidati_post_views" metakey. */
    $ids = $wpdb->get_row("SELECT ID FROM wpdb->posts WHERE post_type IN ('post', 'page') AND post_status = 'publish' AND ID NOT IN (SELECT post_id FROM $wpdb->postmeta WHERE meta_key = 'sidati_post_views')");

    /* After get all posts/pages, now you need to add the meta keys (this may take a few munites if you have many posts/pages)*/
    foreach ($ids as $post_id) {
        add_post_meta($post_id, 'sidati_post_views', 0, true);
    }
}
于 2015-01-16T04:36:56.657 に答える