J'utilise une requête SELECT étrange pour calculer la moyenne de toutes les notes de publication (stockées dans wp_postmeta
) pour un utilisateur donné.
Ma requête utilise essentiellement les arguments suivants:
post_author = 1
ANDmeta_key = 'rating'
ANDmeta_value != 0
.
Cette requête fonctionne parfaitement bien d'elle-même, mais voici où cela se complique. J'ai besoin d'ajouter quelques exceptions ...
meta_key = 'anonymous'
ETmeta_value != 'true'
Et un autre...
meta_key = 'original_author'
ETmeta_value = ''
Je souhaite récupérer uniquement les valeurs méta_valeurs rating
, de sorte que je rencontrerai probablement davantage de problèmes avec $wpdb->postmeta.meta_value
.
Cela totalise jusqu'à 3 arguments meta_key
et meta_value
, avec un seul meta_value
que je souhaite récupérer. Cela devient de plus en plus délicat ...
Voir mon code ci-dessous:
// 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;
}
Votre requête est incorrecte. Pour récupérer des méta-valeurs pour triple meta_key, vous aurez besoin de 3 jointures différentes à l'aide de la table posts meta on posts. Vérifiez le code ci-dessous:
// 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);
Pour récupérer des métadonnées à l'aide d'une requête personnalisée, vous aurez besoin d'une jointure pour chaque paire de métadonnées sur la table des publications, comme ci-dessus.
si vous imprimez la dernière requête SQL en utilisant le code echo $wpdb->last_query;
, vous obtiendrez la requête 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) = ''
)
Il n’ya rien de mal à l’autre réponse, mais j’ai pensé que j’ajouterais cette méthode de manière différente, car c’est simple et elle utilise WP pour élaborer la requête SQL. Ce serait un peu plus lourd en ressources car il y a des requêtes supplémentaires avec la fonction 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;
}
Il est cependant simple à lire et à comprendre et tant que cela ne fonctionne pas en masse (par exemple pour tous vos utilisateurs à la fois), cela devrait convenir pour les ressources.