Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 20-01-2013 22:24:14

Thoomaas
Membre
Date d'inscription: 31-10-2011
Messages: 17

[Résolu] Requête SQL avec résultats aléatoires

Bonjour,

Je souhaite récupérer X enregistrements aléatoires dans une table de ma base de données.

Actuellement, je procède de la sorte :

Code:

[lang=php]
    public function fetchRandomPosts($number) {
        $result = $this->tableGateway->select(
                function(Select $select) use ($number) {
                    $select->limit($number);
                }
        );
        return $result;
    }

La limite fonctionne, mais je ne trouve pas comment générer un rand() SQL avec Zend.

Connaissez-vous une bonne manière de le faire ?

Merci.

Dernière modification par Thoomaas (23-01-2013 15:11:20)

Hors ligne

 

#2 21-01-2013 09:50:21

Orkin
Administrateur
Lieu: Paris
Date d'inscription: 09-12-2011
Messages: 1261

Re: [Résolu] Requête SQL avec résultats aléatoires

Salut, je ne sais pas s'il y a une bonne méthode avec Zend mais ça se fait dans la clause Order By de cette façon :

Code:

[lang=sql]SELECT * FROM MA_TABLE ORDER BY RAND() LIMIT 10

Faut savoir que c'est très très très gourmand est dégueulasse comme requête. On doit pouvoir faire autrement mais je n'ai pas trouvé donc à utiliser avec parcimonie. Cette requête va récupérer l'ensemble des résultats de ta table même avec un limit et va te retourner aléatoirement les 10 premiers résultats. Contrairement à ce qu'on pense limit ne limite pas la requête SQL mais seulement le retour wink

Hors ligne

 

#3 21-01-2013 10:03:32

J0r
Membre
Date d'inscription: 27-04-2012
Messages: 57

Re: [Résolu] Requête SQL avec résultats aléatoires

Mettre un colonne de type int unique dans la table et gérer l'alléatoire avant l'exécution de la requête.

Code:

[lang=sql]
SELECT * FROM MA_TABLE WHERE MA_COLONNE_INT IN (1,124,56124, ....) ORDER BY MA_COLONNE_INT

Si tu mets un index sur MA_COLONNE_INT ça prendra très peux de ressource.

Hors ligne

 

#4 21-01-2013 10:10:23

Orkin
Administrateur
Lieu: Paris
Date d'inscription: 09-12-2011
Messages: 1261

Re: [Résolu] Requête SQL avec résultats aléatoires

Ca peux fonctionner aussi mais ceci implique de connaitre tous les ID de la table avant car si l'ID a été supprimé ou n'existe pas les résultats ne seront pas bon.

Hors ligne

 

#5 21-01-2013 15:43:56

Juch
Membre
Lieu: Paris 17e
Date d'inscription: 29-04-2009
Messages: 48

Re: [Résolu] Requête SQL avec résultats aléatoires

Tout dépend de ta base de données.
Si c'est MySql tu peux faire ça

public function fetchRandomPosts($number) {
    $result = $this->tableGateway->select(
            function(Select $select) use ($number) {
                $select->limit($number)->order('RAND()');
            }
    );
    return $result;
}

Hors ligne

 

#6 22-01-2013 21:14:31

Thoomaas
Membre
Date d'inscription: 31-10-2011
Messages: 17

Re: [Résolu] Requête SQL avec résultats aléatoires

Merci à tous pour vos diverses réponses.

Je suis assez étonné que Zend ne propose pas ce genre d'options. Peut-être que l'explication d'Orkin sur la "dégueulassité" de la requête en est la cause.

Ayant une base MySQL, j'ai souhaité opter pour la solution de Juch, mais j'obtiens l'erreur suivante :

Code:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'RAND`(`)' in 'order clause'

Et sinon, récupérer l'identifiant minimal et le maximal dans la table, tirer au sort des ids compris dans l'intervalle de ces deux valeurs (en PHP), puis récupérer les informations des posts tirés dans la base -> cela devrait être moins gourmand et plus efficace, non ?

On aura certes deux requêtes (celle pour min/max puis celle pour les infos) contrairement à une (avec un simple Rand()) mais les requêtes seront plus légères.

Qu'en pensez-vous ?

Merci !

Hors ligne

 

#7 23-01-2013 01:19:54

Juch
Membre
Lieu: Paris 17e
Date d'inscription: 29-04-2009
Messages: 48

Re: [Résolu] Requête SQL avec résultats aléatoires

et bien écoute moi c'est ce que j'utilise personnellement quand je veux faire un rand()
apres tout dépend de ta version de ZF, tu utilises laquelle ?

Hors ligne

 

#8 23-01-2013 08:56:12

Orkin
Administrateur
Lieu: Paris
Date d'inscription: 09-12-2011
Messages: 1261

Re: [Résolu] Requête SQL avec résultats aléatoires

Thoomaas a écrit:

Et sinon, récupérer l'identifiant minimal et le maximal dans la table, tirer au sort des ids compris dans l'intervalle de ces deux valeurs (en PHP), puis récupérer les informations des posts tirés dans la base -> cela devrait être moins gourmand et plus efficace, non ?

On aura certes deux requêtes (celle pour min/max puis celle pour les infos) contrairement à une (avec un simple Rand()) mais les requêtes seront plus légères.

Qu'en pensez-vous ?

Merci !

Je ne voudrais pas trop m'avancer mais de mémoire c'est moins gourmand de faire les deux requêtes tel que tu le dis plutôt qu'un rand. Le problème de cette solution le voici :

Exemple :
Tu as une table qui a comme id min : 1 et comme id max : 15. Pour une raison X ou Y tu as supprimé les id 8 et 9. Tu as donc toujours le même minimum et maximum pour les id mais au lieu d'en avoir 15 tu n'en as plus que 13. Tu veux récupérer 10 éléments au hasard dans cette table, lorsque tu vas faire ton rand entre 1 et 15 la fonction va te retourner les 10 id aléatoire. Le problème est que si tu tombes sur les id 8 et 9 ta requête retournera que 8 éléments au lieu de 10


Donc même si la solution est dégueulasse de mettre un rand dans le order by c'est malheureusement une des meilleures solution mais la requête est vraiment plus gourmande.
Sinon tu peux essayer de récupérer tous les éléments de la table (s'il n'y a pas trop de jointures ça devrait pas être trop long) et via PHP en récupérer que 10 aléatoirement.

Concernant ton problème de requête, pour ma part j'utilise doctrine et j'ai du l'écrire en SQL pure sans passer par du DQL (Doctrine Query Language)

Hors ligne

 

#9 23-01-2013 10:24:28

jmleroux
Membre
Lieu: Nantes
Date d'inscription: 14-11-2012
Messages: 32
Site web

Re: [Résolu] Requête SQL avec résultats aléatoires

Thoomaas a écrit:

Bonjour,

Je souhaite récupérer X enregistrements aléatoires dans une table de ma base de données.

Actuellement, je procède de la sorte :

Code:

[lang=php]
    public function fetchRandomPosts($number) {
        $result = $this->tableGateway->select(
                function(Select $select) use ($number) {
                    $select->limit($number);
                }
        );
        return $result;
    }

La limite fonctionne, mais je ne trouve pas comment générer un rand() SQL avec Zend.

Connaissez-vous une bonne manière de le faire ?

Merci.

Je ne me suis pas penché sur la récupération aléatoire, mais il y a quelque chose de sûr : ce code récupère toujours les mêmes enregs, c'est juste la limite qui sera aléatoire... wink

Hors ligne

 

#10 23-01-2013 10:46:36

Orkin
Administrateur
Lieu: Paris
Date d'inscription: 09-12-2011
Messages: 1261

Re: [Résolu] Requête SQL avec résultats aléatoires

C'est normal c'est ce qu'il cherche à faire ... wink

Hors ligne

 

#11 23-01-2013 10:51:53

Juch
Membre
Lieu: Paris 17e
Date d'inscription: 29-04-2009
Messages: 48

Re: [Résolu] Requête SQL avec résultats aléatoires

Bon à mon avis ça doit venir de ta version de ZF car je n'ai aucun problème.

Essaie ça :

Code:

$select->order( array( new Zend_Db_Expr('RAND()') ) );

Hors ligne

 

#12 23-01-2013 13:58:35

Thoomaas
Membre
Date d'inscription: 31-10-2011
Messages: 17

Re: [Résolu] Requête SQL avec résultats aléatoires

@Orkin : Je vais me pencher sur ta dernière proposition, de tout récupérer puis d'en choisir un certain nombre en PHP. C'est vrai que si LIMIT ne fait que "cacher" des résultats, autant faire le traitement RAND en PHP. Merci !

@Juch : J'utilise la dernière version disponible via composer (2.*).

Hors ligne

 

#13 23-01-2013 14:35:53

Juch
Membre
Lieu: Paris 17e
Date d'inscription: 29-04-2009
Messages: 48

Re: [Résolu] Requête SQL avec résultats aléatoires

ah ok j'avais pas vu que tu étais en ZF2 au temps pour moi

donc faut utiliser Zend\Db\Sql\Expression
voici l'exemple pour ton problème

Code:

[lang=php]public function fetchRandomPosts($number) {
    $result = $this->tableGateway->select(
            function(Select $select) use ($number) {
                $select->limit($number)->order( array( new Expression('RAND()') ) );
            }
    );
    return $result;
}

En considérant qu'il restait un problème il n'y a pas longtemps et pas sur que ça soit corriger sur ta release.
cf. https://github.com/zendframework/zf2/pull/3017

Dernière modification par Juch (23-01-2013 14:37:06)

Hors ligne

 

#14 23-01-2013 15:10:57

Thoomaas
Membre
Date d'inscription: 31-10-2011
Messages: 17

Re: [Résolu] Requête SQL avec résultats aléatoires

En effet, ça marche beaucoup mieux comme ça. Je vais procéder, pour l'instant, de cette façon.

Je garde quand même de côté la remarque d'Orkin concernant la lourdeur de la requête et j'aviserais après avoir effectué plusieurs tests.

Merci à tous, c'est donc résolu smile !

Hors ligne

 

#15 25-01-2013 11:22:36

Nirzol
Membre
Date d'inscription: 11-01-2013
Messages: 65

Re: [Résolu] Requête SQL avec résultats aléatoires

Sinon tu as : http://php.net/manual/fr/function.array-rand.php
pour le faire en php

Hors ligne

 

#16 26-01-2013 18:18:46

Thoomaas
Membre
Date d'inscription: 31-10-2011
Messages: 17

Re: [Résolu] Requête SQL avec résultats aléatoires

Oui, je ferais les traitements en PHP si je vois que le SQL est trop gourmand ;-) !

Hors ligne

 

Pied de page des forums

Propulsé par PunBB
© Copyright 2002–2005 Rickard Andersson
Traduction par punbb.fr

Graphisme réalisé par l'agence Rodolphe Eveilleau
Développement par Kitpages