特定のユーザーの投稿評価(wp_postmeta
に格納)の平均を計算するために、奇妙なSELECTクエリを使用しています。
私のクエリは基本的に以下の引数を使用します。
post_author = 1
ANDmeta_key = 'rating'
ANDmeta_value != 0
。
このクエリは、それ自体では完全にうまく機能しますが、複雑になるのはここです。私はいくつかの例外を追加する必要があります...
meta_key = 'anonymous'
ANDmeta_value != 'true'
そしてもう一つ...
meta_key = 'original_author'
ANDmeta_value = ''
rating
meta_valuesのみを取得したいので、おそらく$wpdb->postmeta.meta_value
を使用してもっと問題に遭遇するでしょう。
これは全部で3つのmeta_key
とmeta_value
引数になります。実際に取得したいのは1つのmeta_value
だけです。それはちょうどますますトリッキーになります...
下記の私のコードを参照してください。
// Example value
$user_id = 1;
// Calculate average post rating for user
$ratings_query = $wpdb->get_results(
$wpdb->prepare("
SELECT $wpdb->postmeta.meta_value
FROM $wpdb->postmeta
JOIN $wpdb->posts ON ($wpdb->postmeta.post_id = $wpdb->posts.id)
WHERE (
$wpdb->posts.post_author = %d AND
$wpdb->posts.post_type = 'post' AND
$wpdb->posts.post_status = 'publish' AND
$wpdb->postmeta.meta_key = 'rating' AND
$wpdb->postmeta.meta_value != 0
AND
$wpdb->postmeta.meta_key = 'anonymous' AND
$wpdb->postmeta.meta_value != 'true'
AND
$wpdb->postmeta.meta_key = 'original_author' AND
$wpdb->postmeta.meta_value = '')
", $user_id), ARRAY_N);
if ( $ratings_query ) {
$ratings_query = call_user_func_array('array_merge', $ratings_query);
$average_rating = round(array_sum($ratings_query) / count($ratings_query), 1);
} else {
$average_rating = 0;
}
あなたのクエリは正しくありません。 triple meta_keyのメタ値を取得するには、postsテーブルにposts metaを使用して3つの異なる結合が必要です。下記のコードを確認してください。
// Example value
$user_id = 1;
// Calculate average post rating for user
$ratings_query = $wpdb->get_results(
$wpdb->prepare("
SELECT pmeta.meta_value
FROM wp_posts
LEFT JOIN $wpdb->postmeta AS pmeta
ON (pmeta.post_id = $wpdb->posts.id)
LEFT JOIN $wpdb->postmeta AS pmeta1
ON (pmeta1.post_id = $wpdb->posts.id)
LEFT JOIN $wpdb->postmeta AS pmeta2
ON (pmeta2.post_id = $wpdb->posts.id)
WHERE $wpdb->posts.post_author = %d AND
$wpdb->posts.post_type = 'post' AND
$wpdb->posts.post_status = 'publish'
AND (
pmeta.meta_key = 'rating'
AND CAST(pmeta.meta_value AS CHAR) != '0'
)
AND (
pmeta1.meta_key = 'anonymous'
AND CAST(pmeta1.meta_value AS CHAR) != 'true'
)
AND (
pmeta2.meta_key = 'original_author'
AND CAST(pmeta2.meta_value AS CHAR) = ''
)", $user_id), ARRAY_N);
カスタムクエリを使用してメタデータを取得するには、上記のようにpostsテーブルのメタデータペアごとに1つの結合が必要です。
最後のSQLクエリをコードecho $wpdb->last_query;
を使って出力すると、SQLクエリが返されます。
SELECT
pmeta.meta_value
FROM
wp_posts
LEFT JOIN wp_postmeta AS pmeta
ON (pmeta.post_id = wp_posts.id)
LEFT JOIN wp_postmeta AS pmeta1
ON (pmeta1.post_id = wp_posts.id)
LEFT JOIN wp_postmeta AS pmeta2
ON (pmeta2.post_id = wp_posts.id)
WHERE wp_posts.post_author = 1
AND wp_posts.post_type = 'post'
AND wp_posts.post_status = 'publish'
AND (
pmeta.meta_key = 'rating'
AND CAST(pmeta.meta_value AS CHAR) != '0'
)
AND (
pmeta1.meta_key = 'anonymous'
AND CAST(pmeta1.meta_value AS CHAR) != 'true'
)
AND (
pmeta2.meta_key = 'original_author'
AND CAST(pmeta2.meta_value AS CHAR) = ''
)
他の答えに問題はありませんが、単純でSQLクエリを作成するためにWPを使用するので、これを別の方法として追加することを考えました。 get_post_meta
関数を使用した追加のクエリがあるため、リソースが多少重くなります。
$user_id = 1;
$args = array(
'post_type' => 'post',
'posts_per_page' => -1,
'post_status' => 'publish',
'orderby' => 'date',
'order' => 'ASC',
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'post_author',
'value' => $user_id
),
array(
'key' => 'rating',
'compare' => '!=', // or'>'
'value' => 0
),
array(
'key' => 'anonymous',
'compare' => '!=',
'value' => true
),
array(
'key' => 'original_author',
'compare' => '!=',
'value' => ''
)
)
);
$RelevantPosts = get_posts($args);
$ratings = array();
foreach($RelevantPosts as $RelevantPost) {
$ratings[] = get_post_meta($RelevantPost->ID, 'rating' , true);
}
if ( $RelevantPosts ) {
$average_rating = round(array_sum($ratings) / count($ratings), 1);
} else {
$average_rating = 0;
}
しかし、読みやすく理解しやすいもので、大量に実行されない限り(たとえば、すべてのユーザーにとって同時に)、リソースとしては問題ないはずです。