Requête SQL pour obtenir un enregistrement au hasard
Ça m'arrive souvent qu'un client me demande de faire afficher un élément aléatoire dans une page web. Que ce soit pour placer une publicité, mettre un produit en vedette ou pour faire afficher une rubrique "saviez-vous que", c'est le genre de fonctionnalité qui revient constamment et qui permet de mettre un peu de dynamisme dans l'affichage.
De plus, c'est très facile à faire lorsque le contenu est dynamique et géré par un CMS puisqu'on trouve normalement une référence sur les enregistrements dans la base de données. Voici une façon simple d'obtenir un enregistrement aléatoire à partir d'une requête SQL sur trois types de bases de données différentes.
PostgreSQL
Pour obtenir un enregistrement au hasard, on utilisera la fonction mathématique random() qui permet de générer un nombre flotant de 0 à 1. Comme chaque enregistrement se verra associé à un nombre aléatoire, on pourra le classer en ordre et restreindre le nombre de résultats retournés en utilisant la clause LIMIT.
SELECT *SQL Server
FROM table
WHERE condition
ORDER BY random()
LIMIT 1
Du côté de SQL Server, on pourra arriver au même résultat en utilisant la fonction newid(), qui crée un identificateur unique (de type uniqueidentifier) souvent nommé GUID (Globally Unique Identifier) ou UUID (Universally Unique Identifier). Ici, l'équivalent de LIMIT est le mot réservé TOP placé en début de requête.
SELECT TOP 1 *SQL Server possède une fonction rand() pour obtenir un float entre 0 et 1, mais elle est appelée une seule fois à l'intérieur de la requête, donnant toujours le même résultat et rendant impossible l'effet "aléatoire". C'est pourquoi on doit utiliser la fonction newid() qui est non-déterministe, c'est-à-dire qu'elle retournera une valeur différente pour chaque enregistrement (pour visualiser ce qui se passe, placez le dans la liste des colonnes du SELECT *, rand(), newid()...).
FROM table
WHERE condition
ORDER BY newid()
MySQL
Même si j'ai utilisé moins souvent MySQL dans mes projets, j'ai pu obtenir le même comportement avec la fonction rand(), équivalente au random() de PostgreSQL.
SELECT *
FROM table
WHERE condition
ORDER BY rand()
LIMIT 1