Eu tive um problema semelhante recentemente, precisei de 7 metadados de um tipo de postagem personalizado, mas também precisava obter a postagem com base em um metadado.
Então eu criei a seguinte instrução SQL, eu a uso com frequência.
Espero que ajude alguém. Vou tentar explicá-lo o melhor que puder.
global $wpdb;
$pt = 'clients';
$mk = 'trainerid';
$mv = $pid;
$mk1 = 'email';
$mk2 = 'phone';
$mk3 = 'gender';
$mk4 = 'dob';
$mk5 = 'photo';
$mk6 = 'registrationts';
$mk7 = 'activationts';
$ord = 'p.post_name ASC';
$sql = "
SELECT p.ID, p.post_title AS fullname, pm1.meta_value AS email, pm2.meta_value AS phone, pm3.meta_value AS gender, pm4.meta_value AS dob, pm5.meta_value AS photo, pm6.meta_value AS regts, pm7.meta_value AS actemailts
FROM {$wpdb->posts} p
LEFT JOIN {$wpdb->postmeta} pm ON pm.post_id = p.ID
AND pm.meta_key = '{$mk}'
LEFT JOIN {$wpdb->postmeta} pm1 ON pm1.post_id = p.ID
AND pm1.meta_key = '{$mk1}'
LEFT JOIN {$wpdb->postmeta} pm2 ON pm2.post_id = p.ID
AND pm2.meta_key = '{$mk2}'
LEFT JOIN {$wpdb->postmeta} pm3 ON pm3.post_id = p.ID
AND pm3.meta_key = '{$mk3}'
LEFT JOIN {$wpdb->postmeta} pm4 ON pm4.post_id = p.ID
AND pm4.meta_key = '{$mk4}'
LEFT JOIN {$wpdb->postmeta} pm5 ON pm5.post_id = p.ID
AND pm5.meta_key = '{$mk5}'
LEFT JOIN {$wpdb->postmeta} pm6 ON pm6.post_id = p.ID
AND pm6.meta_key = '{$mk6}'
LEFT JOIN {$wpdb->postmeta} pm7 ON pm7.post_id = p.ID
AND pm7.meta_key = '{$mk7}'
WHERE pm.meta_value = '{$mv}'
AND p.post_type = '{$pt}'
AND p.post_status NOT IN ('draft','auto-draft')
ORDER BY {$ord}
";
$clients = $wpdb->get_results( $wpdb->prepare( $sql ), OBJECT );
Primeiro, eu obtenho as funções do banco de dados wordpress com o $ wpdb global.
Então eu configurei o posttype com $ pt.
Para obter o post correto que corresponde a um valor específico em post_meta, eu defino o $ mk (meta_key)
Então eu defino o var de $ mv (meta_value). (neste caso, o valor meta corresponde a um postid)
$ mk1- $ mk7 são as meta_keys que eu quero em cada post. (Eu vou pegar os valores na declaração select)
Eu também faço o 'order by' um var, definindo $ ord
A instrução select é a seguinte:
Eu seleciono o ID do post e o post_title do POST ou 'p.'
Depois, seleciono todos os metadados que preciso selecioná-los com pm1. - > pm.7 e pegar o meta_value e renomeá-los (AS) para que seja mais legível ao recuperar os dados do meu objeto.
Eu crio um JOIN LEFT para os metadados que preciso corresponder ao post. (pm)
Eu crio 7 left join's para cada um dos metadados que preciso recuperar. (pm1-pm7)
A instrução WHERE baseia-se no primeiro JOGO DE ESQUERDA (pm) para que ele saiba que eu preciso apenas das postagens em que os metadados correspondem.
Eu também adiciono um 'AND' para o tipo de postagem e para os post_statuses que não são rascunhos. (apenas posts publicados)
Por fim, adiciono a cláusula 'order by'.
Isso funciona rápido e com os índices internos do Wordpress, então parece eficiente.
Não sei se algo é melhor que isso, mas se for, adoraria usá-lo.
Espero que isso ajude.
Marcus