web-dev-qa-db-fra.com

Obtenir plusieurs valeurs de champs personnalisés dans une requête $ wpdb

doublon possible:
Comment interroger les publications basées sur les coordonnées lat-lng en tant que méta de publication?

Je souhaite créer une requête $ wpdb qui sélectionne les emplacements les plus proches (type de message personnalisé) à proximité des coordonnées actuelles ($ lat et $ long), mais je ne parviens pas à obtenir deux valeurs de champ personnalisées simultanément (wpfc-latitude et wpfc-longitude ) ...

comment puis-je changer ma requête pour obtenir aussi la longitude?

SELECT $wpdb->posts.ID, $wpdb->posts.post_title, $wpdb->terms.name, $wpdb->postmeta.meta_value AS latitude
FROM $wpdb->posts
LEFT JOIN $wpdb->postmeta ON($wpdb->posts.ID = $wpdb->postmeta.post_id)
LEFT JOIN $wpdb->term_relationships ON($wpdb->posts.ID = $wpdb->term_relationships.object_id)
LEFT JOIN $wpdb->term_taxonomy ON($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
LEFT JOIN $wpdb->terms ON($wpdb->term_taxonomy.term_id = $wpdb->terms.term_id)
WHERE $wpdb->postmeta.meta_key = 'wpcf-latitude'
AND $wpdb->posts.post_status = 'publish' 
AND $wpdb->posts.post_type = 'places'
AND $wpdb->term_taxonomy.taxonomy = 'countries'

MISE À JOUR - LA QUESTION FIXE

Grâce à s_ha_dum, j'ai les deux valeurs avec succès et je peux maintenant calculer la distance et ordonner mon résultat. Ma dernière requête est:

SELECT $wpdb->posts.ID, $wpdb->posts.post_title, $wpdb->terms.name, wpcflat.meta_value AS latitude, wpcflong.meta_value AS longitude,
    6371 * 2 * ASIN ( SQRT (POWER(SIN(($lat - wpcflat.meta_value)*pi()/180 / 2),2) + COS($lat * pi()/180) * COS(wpcflat.meta_value *pi()/180) * POWER(SIN(($long - wpcflong.meta_value) *pi()/180 / 2), 2) ) ) as distance
FROM $wpdb->posts
    LEFT JOIN $wpdb->postmeta as wpcflong ON ($wpdb->posts.ID = wpcflong.post_id)
    LEFT JOIN $wpdb->postmeta as wpcflat ON ($wpdb->posts.ID = wpcflat.post_id)
    LEFT JOIN $wpdb->term_relationships ON($wpdb->posts.ID = $wpdb->term_relationships.object_id)
    LEFT JOIN $wpdb->term_taxonomy ON($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
    LEFT JOIN $wpdb->terms ON($wpdb->term_taxonomy.term_id = $wpdb->terms.term_id)
WHERE $wpdb->posts.ID NOT IN ($post->ID)
AND wpcflat.meta_key = 'wpcf-latitude'
AND wpcflong.meta_key = 'wpcf-longitude'
AND $wpdb->posts.post_status = 'publish' 
AND $wpdb->posts.post_type = 'places'
AND $wpdb->term_taxonomy.taxonomy = 'countries'
ORDER BY distance
LIMIT 20

Est-ce une requête lourde à charger? Savez-vous s'il existe un moyen de l'optimiser?

2
Stefano

Vous allez devoir vous joindre deux fois sur la table postmeta. Quelque chose comme:

SELECT $wpdb->posts.ID, $wpdb->posts.post_title, $wpdb->terms.name, wpcflat.meta_value AS latitude, wpcflong.meta_value AS longitude
FROM $wpdb->posts
/* First Join */
LEFT JOIN $wpdb->postmeta as wpcflong ON $wpdb->posts.ID = wpcflong.post_id
/* Second Join */
LEFT JOIN $wpdb->postmeta as wpcflat ON $wpdb->posts.ID = wpcflat.post_id
LEFT JOIN $wpdb->term_relationships ON($wpdb->posts.ID = $wpdb->term_relationships.object_id)
LEFT JOIN $wpdb->term_taxonomy ON($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
LEFT JOIN $wpdb->terms ON ($wpdb->term_taxonomy.term_id = $wpdb->terms.term_id)
WHERE 1
/* Meta queries for lat and long */
AND wpcflat.meta_key = 'wpcf-latitude'
AND wpcflong.meta_key = 'wpcf-longitude'
/* I don't know what criteria you are using to calculate 'nearest' 
but you'd need more conditions here for that */
AND $wpdb->posts.post_status = 'publish' 
AND $wpdb->posts.post_type = 'places'
AND $wpdb->term_taxonomy.taxonomy = 'countries'

Comme indiqué dans mes commentaires SQL, je ne sais pas ce que vous utilisez comme critère de "plus proche", mais ce code vous permettra de jouer avec les deux méta-valeurs. Ma base de données n'a pas de données lat et longues, je ne peux donc pas tester cela à proprement parler, mais c'est correct en principe, sauf une faute de frappe ou deux ou une autre erreur stupide.

Les sous-requêtes sont une autre solution possible, mais elles ne fonctionnent pas correctement lorsque vous essayez de les trier ou de les filtrer.

2
s_ha_dum