web-dev-qa-db-fra.com

Renvoyer l'ID des auteurs ayant au moins un post

J'ai trouvé un excellent morceau de code ici qui renvoie l'ID des utilisateurs par rôle. Ce que je voudrais faire est de le modifier pour qu'il ne retourne que les identifiants des utilisateurs ayant au moins un message. J'ai essayé de INNER JOIN la table $wpdb->posts et je pense l'avoir fait correctement mais sans en être certain. Voici ce que j'ai jusqu'à présent:

function getUsersByRole( $roles ) {
    global $wpdb;
    if ( ! is_array( $roles ) ) {
        $roles = explode( ",", $roles );
        array_walk( $roles, 'trim' );
    }
    $sql = '
        SELECT  ID, display_name
        FROM ' . $wpdb->users . ' INNER JOIN ' . $wpdb->usermeta . ' ON ' . $wpdb->users . '.ID=' . $wpdb->usermeta . '.user_id
        AND INNER JOIN '. $wpdb->posts .'  ON ' .$wpdb->users . '.ID=' . $wpdb->posts . '.post_author
        WHERE   ' . $wpdb->usermeta . '.meta_key        =       \'' . $wpdb->prefix . 'capabilities\' 
        AND     (
    ';
    $i = 1;
    foreach ( $roles as $role ) {
        $sql .= ' ' . $wpdb->usermeta . '.meta_value    LIKE    \'%"' . $role . '"%\' ';
        if ( $i < count( $roles ) ) $sql .= ' OR ';
        $i++;
    }
    $sql .= ' ) ';
    $sql .= ' ORDER BY display_name ';
    $userIDs = $wpdb->get_col( $sql );
    return $userIDs;
}

Ce que la requête SQL génère

SELECT ID, display_name FROM wp_users INNER JOIN wp_usermeta ON wp_users.ID = ba_usermeta.user_id AND INNER JOIN wp_posts sur wp_users.ID = ba_posts.post_author WHERE wp_usermeta.meta_key = 'wp_demodel') et (wp). OR wp_usermeta.meta_value LIKE '% "éditeur"%') ORDER BY nom_affichage

Je n'ai jamais utilisé INNER JOIN (ou JOIN) pour pouvoir le faire mal. Je pense aussi que j'ai besoin de compter ou de faire quelque chose pour être sûr d'obtenir un résultat.

Toute aide serait géniale

EDIT: Voici le fonctionnement complet en tant que PHP pour tous ceux qui le trouveront plus tard

    function getUsersByRole( $roles ) {
    global $wpdb;
    if ( ! is_array( $roles ) ) {
        $roles = explode( ",", $roles );
        array_walk( $roles, 'trim' );
    }
    $sql = 'SELECT ID, display_name
        FROM '. $wpdb->users .'
        JOIN '. $wpdb->usermeta.' ON ('.$wpdb->users.'.ID = '.$wpdb->usermeta.'.user_id AND '.$wpdb->usermeta.'.meta_key = \''.$wpdb->prefix.'capabilities\')
        WHERE ID IN (SELECT post_author FROM ' .$wpdb->posts.')
        AND(';
    $i = 1;
    foreach ( $roles as $role ) {
        $sql .= ' ' . $wpdb->usermeta . '.meta_value    LIKE    \'%"' . $role . '"%\' ';
        if ( $i < count( $roles ) ) $sql .= ' OR ';
        $i++;
    }
    $sql .= ' ) ';
    $sql .= ' ORDER BY display_name ';
    $userIDs = $wpdb->get_col( $sql );

    return $userIDs;
}
3
Brooke.

Au lieu d'une JOIN, vous pouvez utiliser une IN avec une sous-requête pour éviter les doublons à cause de la jointure:

SELECT ID, display_name
FROM wp_users
WHERE ID IN (SELECT post_author FROM wp_posts)

Cela ne portera pas sur les capacités. Si vous souhaitez également que vous puissiez les ajouter comme une jointure, mais déplacez la clause meta_key dans la jointure, également pour éviter les doublons:

SELECT ID, display_name
FROM wp_users
    JOIN wp_usermeta ON (wp_users.ID = wp_usermeta.user_id AND wp_usermeta.meta_key = 'wp_capabilities')
WHERE ID IN (SELECT post_author FROM wp_posts)
    AND (wp_usermeta.meta_value LIKE '%"author"%'
        OR wp_usermeta.meta_value LIKE '%"editor"%' )

À vous de le reconvertir en PHP! Note: Le wp_ dans wp_capabilities dépend-il du préfixe de la base de données ou est-il toujours wp_, même si vos noms de table commencent par un autre préfixe?

2
Jan Fabry