# WP_Query et meta_value_num : trier des biens immobiliers par prix sans extension

> Un tri par prix qui classe 90 000 avant 100 avant 9 000 : le symptôme classique d'un tri alphabétique sur un champ numérique. Le paramètre orderby meta_value_num corrige ce défaut sans extension tierce.

- Auteur : WordPress Développement
- Publié le : 2021-06-22
- Mis à jour le : 2021-06-22
- Catégorie : Astuces
- URL : https://www.wpmoderne.fr/tips/wp-query-meta-value-num-tri-prix-biens/

## L’essentiel

- meta_value trie comme du texte, meta_value_num trie comme un nombre
- Le type de champ doit rester cohérent à l'enregistrement
- Aucune extension nécessaire pour un tri numérique correct

90 000 avant 100 000, mais aussi avant 9 000 : voilà ce que produisait le tri « prix croissant » d'un site vitrine pour un réseau d'agences immobilières indépendantes, avant que le développeur précédent ne me transmette le dossier. Le prix de chaque bien était stocké en champ personnalisé, trié avec `orderby => 'meta_value'`, un paramètre qui compare les valeurs comme des chaînes de caractères plutôt que comme des nombres.

Le symptôme est trompeur : le tri fonctionne, dans le sens où il classe les biens dans un certain ordre, mais cet ordre est celui de la comparaison alphabétique d'une chaîne. « 90000 » est « plus petit » que « 100000 » alphabétiquement, car le caractère « 9 » vient après « 1 » dans la comparaison caractère par caractère, mais dès le deuxième caractère la comparaison bascule différemment selon la longueur des chaînes. Le résultat paraît aléatoire à qui ne connaît pas la cause exacte.

## Le tri fautif, tel qu'il apparaissait dans le thème

Voici la requête d'origine, qui illustre parfaitement le piège : elle ne produit aucune erreur, aucun avertissement, elle retourne simplement un ordre incorrect, ce qui la rend difficile à repérer sans comparer manuellement les prix affichés.

```
$biens = new WP_Query( array(
    'post_type'  => 'bien',
    'meta_key'   => 'prix_bien',
    'orderby'    => 'meta_value',
    'order'      => 'ASC',
    'posts_per_page' => 20,
) );
```

## La correction : meta_value_num

Le paramètre `orderby` accepte la valeur `meta_value_num`, qui indique explicitement à WordPress de convertir les valeurs en nombre avant de les comparer. C'est un changement d'un seul mot, mais qui suffit à corriger entièrement le classement.

```
$biens = new WP_Query( array(
    'post_type'  => 'bien',
    'meta_key'   => 'prix_bien',
    'orderby'    => 'meta_value_num',
    'order'      => 'ASC',
    'posts_per_page' => 20,
) );
```

> L'essentiel à retenir : meta_value trie comme du texte, meta_value_num trie comme un nombre ; Le type de champ doit rester cohérent à l'enregistrement ; Aucune extension nécessaire pour un tri numérique correct

## Pourquoi le type de champ compte autant que le paramètre orderby

Corriger le paramètre `orderby` ne suffit pas si le champ lui-même contient des valeurs incohérentes : un prix enregistré une fois comme `250000` et une autre fois comme `250 000` avec un espace, ou `250000€` avec le symbole monétaire, casse le tri numérique tout autant qu'un mauvais paramètre. La discipline de saisie compte autant que la requête.

```
add_action( 'save_post_bien', function ( $post_id ) {
    if ( isset( $_POST['prix_bien'] ) ) {
        $prix = preg_replace( '/[^0-9]/', '', $_POST['prix_bien'] );
        update_post_meta( $post_id, 'prix_bien', absint( $prix ) );
    }
} );
```

Cette normalisation à l'enregistrement garantit que le champ ne contiendra jamais que des nombres entiers purs, condition indispensable pour que `meta_value_num` fonctionne de façon fiable sur l'ensemble du catalogue.

## Comparer les deux comportements sur un cas concret

| Prix stockés | Ordre avec meta_value | Ordre avec meta_value_num |
| --- | --- | --- |
| 9 000, 90 000, 100 000 | 100 000, 9 000, 90 000 | 9 000, 90 000, 100 000 |
| 1 200, 850, 15 000 | 1 200, 15 000, 850 | 850, 1 200, 15 000 |

Ce tableau, présenté tel quel à l'équipe du réseau d'agences, a suffi à convaincre que le problème ne venait ni du contenu des fiches ni d'un bug d'affichage, mais bien d'un choix de paramètre à corriger une fois pour toutes.

## Étendre le tri numérique à d'autres champs

Une fois le principe compris, plusieurs autres champs du même site méritaient la même correction, chacun avec sa propre logique de tri :

- La surface habitable, souvent triée par erreur comme du texte pour les mêmes raisons que le prix.
- Le nombre de pièces, un champ court où l'erreur passe presque inaperçue tant que le catalogue reste petit, mais qui devient visible dès qu'il dépasse neuf pièces.
- La date de disponibilité du bien, qui nécessite en revanche `orderby => 'meta_value'` avec un format `Ymd`, car un tri numérique sur une date écrite autrement produirait un résultat tout aussi faux.

> Un tri qui ne renvoie jamais d'erreur mérite d'être vérifié aussi souvent qu'un tri qui plante : l'absence de message ne garantit jamais l'exactitude du résultat.

## Notre verdict

Le paramètre `meta_value_num` de `WP_Query` existe depuis les premières versions de l'API des requêtes personnalisées et ne nécessite strictement aucune extension tierce. Le vrai travail consiste à garantir que les données stockées restent des nombres purs, faute de quoi même le bon paramètre de tri ne produira pas le résultat attendu. Ce dossier ne traite volontairement pas la pagination du listing, qui repose sur une logique distincte, à combiner avec ce tri une fois celui-ci corrigé.
