Partage
  • Partager sur Facebook
  • Partager sur Twitter

[EJB-QL] Compter le top d'entrée d'une table

Sujet résolu
    8 juin 2010 à 20:13:23

    Bonsoir,
    J'aimerais savoir comment faire pour retourner les trois meilleures entrées d'une table ? c.à.d. les trois valeurs les plus répétées dans une colonne ?
    rbv = em.createQuery("SELECT rbv, COUNT(rbv.idVol.idVol) FROM " +
                         "Reservationbilletavion rbv " +
                         "WHERE rbv.archive = 0 " +
                         "GROUP BY rbv.idVol.idVol")
                         .setMaxResults(3)
                         .getResultList();
    

    L'erreur est :
    SQL Error: 979, SQLState: 42000
    ORA-00979: N'est pas une expression GROUP BY

    • Partager sur Facebook
    • Partager sur Twitter
      8 juin 2010 à 20:48:55

      Ne connaissant pas le EJB-QL (mais après une petite recherche, ça semble ressembler beaucoup au SQL "normal", l'idée est d'aller chercher le rang de chaque valeur répétée. En effet, aller chercher "les trois valeurs les plus répétées" est un peu aléatoire : Qu'est-ce qui arrive si deux nombres sont répétés autant de fois ?

      On utilise donc les fonctions de fenêtrage pour obtenir le rang (je suppose que c'est la valeur idVol.aeroArrivee qui se répète et que tu veux sélectionner :
      SELECT idVol.aeroArrive, RANK() OVER(ORDER BY COUNT(*) DESC) as rank
      FROM Reservationbilletavion
      GROUP BY idVol.aeroArrive;
      


      On peut ensuite sélectionner les lignes ayant le rang 1, 2 ou 3 (il peut y en avoir plus que 3) :

      SELECT idVol.aeroArrive
      FROM 
          (
              SELECT idVol.aeroArrive, RANK() OVER(ORDER BY COUNT(*) DESC) as rank
              FROM Reservationbilletavion
              GROUP BY idVol.aeroArrive
          )
      WHERE rank <= 3;
      


      En supposant que le EJB-QL et le SGBDR supporte les fonctions de fenêtrage.
      • Partager sur Facebook
      • Partager sur Twitter
        8 juin 2010 à 21:12:25

        Merci, mais je ne pense pas à ma connaissance que le fenêtrage en EJB3 soit supporté. J'apprécie ton aide.
        List<Integer> rbv = null;
                 try{
                    rbv = em.createQuery("SELECT rbv.idVol.idVol " +
                                         "FROM Reservationbilletavion rbv " +
                                         "WHERE (LE PLUS DE REPETITION) AND rbv.archive = 0 " +
                                         "GROUP BY rbv.idVol.idVol")
                                         .setMaxResults(3)
                                         .getResultList();
        

        PS : le premier idVol correspond à la clé étrangère d'une table, le second est sa clé primaire.
        Il me manque juste à sélectionner les idVol les plus répétitifs, je peux faire cela en Java mais j'aimerais me baser un peu sur EJB-QL. Comment faire ?


        • Partager sur Facebook
        • Partager sur Twitter
        Anonyme
          8 juin 2010 à 21:29:20

          C'est un problème de "EJBQL", ou de SQL ?
          Parce que ce que tu montres là, c'est du SQL, non ?

          Citation


          SQL Error: 979, SQLState: 42000
          ORA-00979: N'est pas une expression GROUP BY


          C'est une erreur d'Oracle (SQL) assez explicite.

          La requête de Fayden devrait passer sur Oracle.
          • Partager sur Facebook
          • Partager sur Twitter
            8 juin 2010 à 21:52:34

            La question n'est pas de savoir quel ou quel SGBD j'utilise, la couche JDBC m'est transparente. La syntaxe d'EJB-QL est la même pour tout les SGBD qu'hibernate implémente. Oracle 10g peut supporter les fenêtrages mais EJB-QL non, car ils peuvent ne pas être supportés par d'autres SGBD.
            La bonne réponse est :
            rbv = em.createQuery("SELECT rbv.idVol.idVol " +
                                 "FROM Reservationbilletavion rbv " +
                                 "WHERE rbv.archive = 0 " +
                                 "GROUP BY rbv.idVol.idVol " +
                                 "ORDER BY COUNT(rbv.idVol.idVol) DESC")
                                 .setMaxResults(3)
                                 .getResultList();
            

            Avec un peut d'astuce on peut arriver à tout ^^ .
            • Partager sur Facebook
            • Partager sur Twitter
              8 juin 2010 à 22:01:12

              Comme je l'ai dit plus haut, ça en sélectionne toujours trois, indépendamment des éventuelles égalités.
              • Partager sur Facebook
              • Partager sur Twitter
                8 juin 2010 à 22:13:52

                Voici mes lignes d'exemples :
                Image utilisateur
                Et regardez le résultat de la requête, ça prouve que c'est bien correcte :
                <?xml version="1.0" encoding="UTF-8"?>
                <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
                    <S:Body>
                        <ns2:getTopDestinationResponse xmlns:ns2="http://ws.etdc/">
                            <return xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:long">4</return>
                            <return xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:long">7</return>
                            <return xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:long">2</return>
                        </ns2:getTopDestinationResponse>
                    </S:Body>
                </S:Envelope>
                

                • Partager sur Facebook
                • Partager sur Twitter
                  8 juin 2010 à 22:31:34

                  Je n'ai pas dit que la requête ne fonctionnerait pas, j'ai dit que si deux nombres apparaissent le même nombre de fois, ça ne fonctionnera pas. Si on prend cette exemple :

                  1
                  1
                  1
                  1
                  1
                  2
                  2
                  2
                  2
                  3
                  3
                  3
                  4
                  4
                  4

                  On choisit quoi ? 1, 2 et 3 ou 4 ? Ma requête les sélectionnerait tous (c'est normal, si on veut choisir les trois premiers). La tienne sélectionne 3 ou 4 au hasard.
                  • Partager sur Facebook
                  • Partager sur Twitter
                    8 juin 2010 à 22:38:17

                    Ah ok, oui ça sélectionne un au hasard je l'avais remarqué. Mais bon, il n y a pas de priorité entre les vols :) . Je vous remercie pour votre aide précieuse.
                    • Partager sur Facebook
                    • Partager sur Twitter

                    [EJB-QL] Compter le top d'entrée d'une table

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                    • Editeur
                    • Markdown