[SQL] comparaison Résultat

Résolu
Passarinho44 Messages postés 977 Statut Contributeur -  
X-Fan Messages postés 811 Statut Membre -
Bonjour,

Je travaille en SQL et je précise que je ne peux pas utiliser autre chose.

En fait mon problème est que je retourne un résultat du type :

ID secondaire | Commentaire
1 | Commentaire1
1 | Commentaire2
1 | Commentaire3
2 | Commentaire1
... | ...

Et je voudrais faire une requête qui me permettrait de comparer le résultat de l'ID secondaire avec le suivant (ici d'abord 1 avec 1, puis 1 avec 1, puis 1 avec 2 ... etc... )

Et n'afficher un résultat que lorsque les deux sont différents

(Donc en clair ça doit m'afficher le dernier commentaire de chaque ID secondaire.

Je sais pas si c'est très clair... ^^"

Demandez moi si vous voulez plus de précisions.

Merci d'avance pour vos réponses =)

26 réponses

  • 1
  • 2
Résumé de la discussion

La problématique porte sur l'extraction du dernier commentaire par ID secondaire dans un jeu de résultats SQL où chaque ID secondaire peut apparaître plusieurs fois avec des commentaires différents. Plusieurs réponses suggèrent d'isoler le dernier commentaire de chaque ID secondaire à l'aide d'une sous-requête ou d'un TOP 1 avec tri par le champ commentaire, afin d'obtenir une ligne par identifiant. En pratique, des difficultés apparaissent lorsque l'ID est text et nécessite une conversion vers int via Convert(int, …), avec des GROUP BY ou des conversions dans les sous-requêtes pour permettre le tri. Des détails pratiques évoquent l'impossibilité de trier des champs text sans conversion et les limites liées à l'utilisation de TOP 1 selon l'environnement SQL, ainsi que des conseils pour tester localement les résultats.

Généré automatiquement par IA
sur la base des meilleures réponses
  1. X-Fan Messages postés 811 Statut Membre 24
     
    J'ai rien compris XD
    5
  2. Passarinho44 Messages postés 977 Statut Contributeur 132
     
    En clair j'ai des ID (ils peuvent être plusieurs fois les mêmes )...

    Pour chaque ID j'ai plusieurs commentaires.

    Et bien je veux afficher le dernier commentaire de chaqeu ID.

    C'est plus clair?
    3
    1. X-Fan Messages postés 811 Statut Membre 24
       
      Nettement plus clair. Mais donc toi tu voudrais que celui qui reste soit, pour ton ID 1, le commentaire 3 car c'est le dernier. C'est bien cela? Et si j'ai 5 commentaires pour le ID 2, tu voudrais que ce soit le 5ème?
      0
  3. Passarinho44 Messages postés 977 Statut Contributeur 132
     
    Oui voilà c'est ça.

    Il faut donc comparer l'ID avec le suivant, est-ce possible en SQL???
    2
    1. X-Fan Messages postés 811 Statut Membre 24
       
      Il y a tellement de chose possible. Pas besoin de comparer le ID avec le suivant. Attend, je réfléchi parce que j'ai pas, sur le moment, l'idée constructive pour faire ça.
      0
  4. Passarinho44 Messages postés 977 Statut Contributeur 132
     
    L'idée est très bonne.

    Je pense que ça devrait fonctionner mais le problème c'est que mon champ ID est en fait un champ text (il contient par exemple "cr:400019" ) et donc SQL ne veut pas utiliser le = pour la sous-requete

    De quoi corser un peu la chose ;)
    2
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. X-Fan Messages postés 811 Statut Membre 24
     
    Si tu fais un truc du genre:

    SELECT TOP 1 m.idsecondaire, m.commentaire FROM matable m
    HAVING m.idsecondaire = (SELECT DISTINCT(m2.idsecondaire) FROM matable m2) xx
    ORDER BY commentaire DESC

    Essaie un truc du genre mais j'ai rien pour testé et ça fait un petit moment que j'ai pas fait de SQL. Si j'avais le logiciel ici, je pourrais te faire ça et fonctionnel en un rien de temps XD
    1
  7. X-Fan Messages postés 811 Statut Membre 24
     
    Ah! C'est bon à savoir (parce que comparer des 1 c'est pas mal plus facile c'est clair).
    0
  8. Passarinho44 Messages postés 977 Statut Contributeur 132
     
    J'ai appliquer ce que tu m'a mis à mon cas, je l'ai bidouiller dans tout les sens ^^" ... Pas moyen de le faire fonctionner ..

    Le fait que ce soit un champ texte au lieu d'un champ int me renvoie toujours une erreur ... :(

    Donc soit je dis à mon patron de refaire la bdd pour mettre un int (je crois pas qu'il va apprécier ^^ ) soit je trouve un moyen de comparer des champs texte pour faire la sous-requête.

    Tu as une idée?
    0
  9. X-Fan Messages postés 811 Statut Membre 24
     
    J'y pense mais la clause HAVING ne fonctionne pas avec texte donc il faut trouver autre chose ;)
    0
  10. Passarinho44 Messages postés 977 Statut Contributeur 132
     
    Mon champ call_req_id est toujours de la forme "cr:xxxxxx".

    Je me demande donc si on peut pas avec SQL virer les "cr:" puis transformer le résultat en int.

    Ou alors comparer le résultat au suivant (mais toujours le même problème en fait ... ^^ )
    0
    1. X-Fan Messages postés 811 Statut Membre 24
       
      Toujours des numéros après les deux points?
      0
    2. Passarinho44 Messages postés 977 Statut Contributeur 132 > X-Fan Messages postés 811 Statut Membre
       
      Oui, toujours une suite de 6numéros.
      0
    3. X-Fan Messages postés 811 Statut Membre 24 > X-Fan Messages postés 811 Statut Membre
       
      Alors dans ce cas:

      SELECT TOP 1 m.idsecondaire, m.commentaire FROM matable m
      HAVING CONVERT(SUBSTR(m.idsecondaire,3,LEN(m.idsecondaire)) AS int) = (SELECT DISTINCT(CONVERT(SUBSTR(m2.idsecondaire,3,LEN(m2.idsecondaire)) AS int)) FROM matable m2) xx
      ORDER BY m.commentaire DESC
      0
    4. Passarinho44 Messages postés 977 Statut Contributeur 132 > X-Fan Messages postés 811 Statut Membre
       
      Je viens d'essayer les 2 que tu m'as proposé ... Toujours une erreur.

      Par contre pour le dernier l'erreur est diférente : il me dit qu'il y a une erreur de syntaxe près de "," (je sais pas quel virgule par contre >< )

      Voici comment je l'ai adapté, tu trouveras peut-être l'erreur :

      SELECT TOP 1
      t1.call_req_id,
      t1.action_desc
      FROM
      Act_log AS "t1"
      HAVING
      CONVERT(SUBSTR(t1.call_req_id,3,LEN(t1.call_req_id)) AS int) = (SELECT
      DISTINCT(CONVERT(SUBSTR(t2.call_req_id,3,LEN(t2.call_req_id)) AS int))
      FROM
      Act_log AS "t2") xx
      ORDER BY t1.action_desc DESC
      0
    5. X-Fan Messages postés 811 Statut Membre 24 > Passarinho44 Messages postés 977 Statut Contributeur
       
      Le meilleur moyen de savoir c'est de commencer par exécuter celle là toute seule:

      SELECT
      DISTINCT(CONVERT(SUBSTR(t2.call_req_id,3,L­EN(t2.call_req_id)) AS int))
      FROM
      Act_log AS "t2"

      Voir si elle marche et si le résultat retourné est celui désiré.
      0
  11. X-Fan Messages postés 811 Statut Membre 24
     
    SELECT m.idsecondaire, m.commentaire FROM matable m
    INNER JOIN (SELECT TOP 1 * FROM matable m2 ORDER BY commentaire DESC )xx
    ON xx.idsecondaire = m.idsecondaire

    J'ai franchement pas d'idées là tout de suite LOL. Faut que j'y pense mais bref.
    0
  12. X-Fan Messages postés 811 Statut Membre 24
     
    SELECT TOP 1 m.idsecondaire, m.commentaire FROM matable m
    HAVING CONVERT((CONVERT(SUBSTR(m.idsecondaire,3,LEN(m.idsecondaire)) AS varchar(10))) AS int) = (SELECT DISTINCT(CONVERT((CONVERT(SUBSTR(m2.idsecondaire,3,LEN(m2.idsecondair­e)) AS varchar(10)) AS int))) FROM matable m2) xx
    ORDER BY m.commentaire DESC

    Un truc comme ça je suppose.
    0
  13. Passarinho44 Messages postés 977 Statut Contributeur 132
     
    Bonjour,

    Je viens de tester la fonction convert et dans mon logiciel, elle ne fonctionne pas comme en SQL normal.

    Pour convertir en integer je doit faire : Convert(int, t2.ref_num)

    Comme ça, la conversion fonctionne mais par contre le reste non ^^

    J'ai pû faire fonctionner la sous-requête mais là où il y a un problème c'est au niveau du :
    Convert(int, t2.ref_num) = (SELECT DISTINCT Convert(int, t3.ref_num) 'Ref_Num_Test' FROM call_req AS "t3")

    Comme il est dans un HAVING, je dois mettre t2.ref_num dans un GROUP BY avant.

    Seulement le problème est que lorsque je met le t2.ref_num dans un GROUP BY, il me dit qu'il ne peut pas trier des champs text (il ne prend pas la conversion dans le GROUP BY ... )
    0
  14. X-Fan Messages postés 811 Statut Membre 24
     
    Tu peux mettre:
    GROUP BY Convert(int, t3.ref_num)

    Je ne pense pas que ce soit interdit. Mais sinon, est-ce que tu as pu faire marcher substring?
    0
  15. Passarinho44 Messages postés 977 Statut Contributeur 132
     
    Non, il ne substring ne fonctionne pas mais en fait je n'en ai pas besoin : j'utilise un autre champ qui ne comporte que des chiffres donc plus de problème de ce côté là.

    Je n'ai même plus de problème pour la conversion en integer.

    J'ai trouvé sur un autre forum une personne qui avait un problème un peu similaire.

    En essayant d'adapter son code j'arrive à ça mais toujours quelques soucis : il me dit que la colonne ref_num est invalide.
    Je ne sais pas trop utiliser l'inner join donc bon ... :s

    SELECT
    Convert(int, t2.ref_num) "Ref_Num",
    t2.description
    FROM
    call_req "t2",
    Act_log "t1"
    INNER JOIN
    (
    SELECT
    Max(t1.ref_num),
    t2.id
    FROM
    Act_log "t1",
    call_req "t2"
    WHERE
    t1.type = 'LOG'
    AND t1.call_req_id = t2.persid
    GROUP BY
    t1.id
    ) As "DernierEnrs"
    ON t1.id=DernierEnrs.id
    AND t1.ref_num=DernierEnrs.ref_num
    WHERE
    t1.type = 'LOG'
    AND t1.call_req_id = t2.persid
    GROUP BY t2.id
    0
  16. Passarinho44 Messages postés 977 Statut Contributeur 132
     
    Sinon, en adaptant ce que tu m'a proposé pour qu'il n'y ait plus d'erreur j'arrive à ça :

    SELECT
    Convert(int, t2.ref_num) "Ref_Num",
    t1.description
    FROM
    Act_log "t1",
    call_req "t2"
    WHERE
    t1.type = 'LOG'
    AND t1.call_req_id = t2.persid
    AND t2.ref_num >= '105410'
    AND t2.ref_num <= '105420'
    AND Convert(int,t2.ref_num) IN
    (SELECT DISTINCT Convert(int, t3.ref_num)
    FROM
    call_req "t3"
    WHERE
    t3.ref_num >= '105410'
    AND t3.ref_num <= '105420'
    GROUP BY Convert(int, t3.ref_num))
    ORDER BY Convert(int, t2.ref_num)

    Mais ça ne m'affiche pas ce que je veux...

    Ca m'affiche les ID avec tous les commentaires pour chaque ID.
    0
    1. X-Fan Messages postés 811 Statut Membre 24
       
      INNER JOIN ne sert qu'à lier deux tables sur un champ commun. Tu n'es pas supposé de retirer de l'information avec cette clause. C'est la clause HAVING ou WHERE qui doit servir à sélectionner des enregistrements filtrés.
      0
      1. Passarinho44 Messages postés 977 Statut Contributeur 132 > X-Fan Messages postés 811 Statut Membre
         
        D'accord, donc on oublie le INNER JOIN pour cette question.

        Tu as une idée pour afficher seulement le dernier commentaire?

        Parce que moi à part comparer la valeur du ref_num avec la valeur suivante je vois pas ..
        0
  17. X-Fan Messages postés 811 Statut Membre 24
     
    c'est quoi ton champ qui est seulement numérique là ? Et est-ce que c'est toujours la même valeur pour un même idsecondaire (donc on pourrait l'utiliser pour travailler comme si on utilisait le idsecondaire)?
    0
  18. Passarinho44 Messages postés 977 Statut Contributeur 132
     
    Oui oui, il vient d'une autre table mais pas de problème pour l'intégrer et il correspond à l'id secondaire du début mais avec la contrainte du text en moins.
    0
  19. X-Fan Messages postés 811 Statut Membre 24
     
    Ok donc tu as

    matable 1
    idsecondaire, commentaire

    matable 2
    idsecondaire, mêmenumerosansleslettres

    C'est ça?
    0
  20. Passarinho44 Messages postés 977 Statut Contributeur 132
     
    Voilà, enfin presque mais ça revient au même ^^

    On va les appeler :

    matable1 "t1" :
    t1.persid, t1.description

    matable2 "t2" :
    t2.persid, t2.ref_num
    0
  21. X-Fan Messages postés 811 Statut Membre 24
     
    ok merci mon chou, ça va déjà être plus facile comme ça XD

    Alors je te montre comment marche inner join. Inner join sert à joindre deux tables ayant des champs en commun.

    Donc, il va te sortir de l'information pour tous les champs ayant une valeur égale selon le champ de référence.

    si j'ai la table:

    matable t1 avec les deux champs id, description et qui contient les lignes suivantes:
    a1, salut
    a1, bonjour
    a2, je suis là
    a3, blabla

    matable t2 avec les deux champs id, ref et qui contient les lignes suivantes:
    a1, 1
    a2, 2
    a3, 3

    Si je vais une inner join, la table virtuel qui va se créer aura l'air de:
    a1, salut, 1
    a1, bonjour, 1
    a2, je suis là, 2
    a3, blabla, 3

    Si maintenant je reprend ma table t1 et que je fais un inner join avec ma table t3
    matable t3 avec les deux champs id, ref et qui contient les lignes suivantes:
    a1, 1
    a2, 2

    le résultat de la table virtuel sera:
    a1, salut, 1
    a1, bonjour, 1
    a2, je suis là, 2

    Est-ce que tu comprends ou j'explique mal XD ?

    Bien entendu, il y a aussi LEFT JOIN, RIGHT JOIN ET FULL JOIN mais bon, pense pas qu'on en aura besoin.
    0
  • 1
  • 2