IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage SQL Discussion :

Problème requête SQL


Sujet :

Langage SQL

  1. #1
    Nouveau membre du Club
    Inscrit en
    Septembre 2005
    Messages
    44
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 44
    Points : 31
    Points
    31
    Par défaut Problème requête SQL
    Salut
    Je voudrait écrire une requête qui renvoie toutes les transactions d'une table qui ont le même idmembre, même id_partenaire, même montant et une date de transaction dont la différence est au plus 5 minutes.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      select count(*), TP.idmembre,TP.montant,TP.id_partenaire  
      from transactions_jour TP inner join transactions_jour   TD on TP.numtransaction_jour=TD.numtransaction_jour
      where TP.datetransaction >= TD.datetransaction and TP.datetransaction <= dateadd(minute,5,TD.datetransaction)
      group by TP.idmembre,TP.montant,TP.id_partenaire
      having count(*) > 1
    J'ai fait une jointure de ma table transactions_jour vers la table transactions_jour mais cela ne marche pas. Elle me renvoie toutes les transactions qui ont même montant, même idmembre et même id_partenaire sans se soucier de la date.

    Si quelqu'un a une idée, merci.

  2. #2
    Membre expert
    Avatar de TheLeadingEdge
    Inscrit en
    Mai 2005
    Messages
    1 199
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 1 199
    Points : 3 103
    Points
    3 103
    Par défaut
    Bonjour,

    Tes 2 tx ont le même numtransaction_jour ?

    Et si tu faisais ta jointure
    sur même montant, même idmembre et même id_partenaire ?

    A +

  3. #3
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut Re: Problème requête SQL
    Citation Envoyé par mandaillou
    J'ai fait une jointure de ma table transactions_jour vers la table transactions_jour mais cela ne marche pas. Elle me renvoie toutes les transactions qui ont même montant, même idmembre et même id_partenaire sans se soucier de la date.
    Cela me semble normal, car dans ta requête chaque ligne se joint avec elle-même, le having count(*) > 1 ne résout pas le problème (et qu'il faudrait enlever), il faudrait que dans ta condition de jointure, tu exclus la possibilité qu'une ligne se joigne avec elle-meme

    par exemple, si IdTransaction est la PK de la table

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT   COUNT(*), TP.IdMembre,TP.Montant,TP.Id_Partenaire 
    FROM     Transactions_jour TP INNER JOIN Transactions_jour TD 
                                          ON TP.NumTransaction_Jour = TD.NumTransaction_Jour 
                                         AND TP.IdTransaction < TD.IdTransaction
    WHERE    TP.DateTransaction >= TD.DateTransaction 
      AND    TP.DateTransaction <= DATEADD(minute,5,TD.DateTransaction) 
    GROUP BY TP.IdMembre,TP.Montant,TP.Id_Partenaire
    Tu risques d'avoir plusieurs la même ligne, par exemple si tu as 3 transactions dans la même tranche de 5 mn, mais pour aller plus loin, il faudrait en savoir plus...

    Je suis aussi d'accord avec la remarque de TheLeadingEdge

  4. #4
    Nouveau membre du Club
    Inscrit en
    Septembre 2005
    Messages
    44
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 44
    Points : 31
    Points
    31
    Par défaut
    Je vais préciser mon problème.

    J'ai une table transactions_jour dans laquelle sont stockées toutes les transactions du jour. Ces transactions sont insérées dans la table à partir de fichiers récupérés chaque jour sur les serveurs des partenaires. Dans ces fichiers, il arrive qu'il y ait des erreurs, c'est à dire qu'une transaction apparaisse plusieurs fois à quelques minutes d'intervalle alors qu'elle ne devrait y être qu'une fois.
    C'est le but de ma requête, retrouver ces transactions en trop. Pour déceler ces transactions erronées, je me base sur l'identifiant du membre (idmembre), l'identifiant du partenaire (idpartenaire) et le montant de la transaction (montant), ainsi que sur la date de la transaction qui doit être différente de moins de 5 minutes. En effet, les probabilités qu'un membre fasse deux fois une transaction du même montant chez le même partenaire à moins de 5 minutes d'intervalle est quasiment nulle.
    J'utilise un count(*) couplé avec un having count(*) > 1 pour ne récupérer que les transactions qui apparaissent plusieurs fois. Si je ne le mets pas, je vais récupérer toutes les transactions de la table. De cette façon, je n'aurais qu'une seule transaction de chaque groupe de transactions litigieuses. Dans une autre requête se basant sur celle-ci, je les récupère toutes. Je ne vois pas comment faire sans utiliser un count(*).
    Le problème vient de la restriction sur la date, c'est pourquoi j'ai joint la table avec elle même.
    Numtransaction_jour est l'id de la table.
    Voila, j'espère que j'ai éclairci mon problème.

  5. #5
    Membre expert
    Avatar de TheLeadingEdge
    Inscrit en
    Mai 2005
    Messages
    1 199
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 1 199
    Points : 3 103
    Points
    3 103
    Par défaut
    Bonjour,

    Tes 2 tx ont le même numtransaction_jour ?

    Je ne vois pas la réponse dans tes explications (ou alors je ne suis pas bien réveillé, ce qui est 1 hypothèse que je ne néglige pas ;-) ) ...
    donc je reformule différement :

    - Existe-t-il plusieurs tuples avec le même numtransaction_jour et 1 DateTransaction différent?
    ou
    - numtransaction_jour est-il discriminant à lui-seul ?

    [edit]1 bon exemple valant mieux qu'1 long discours,
    peux-tu poster 1 petit extrait significatif de ta table ? [/edit]
    A +

  6. #6
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    Si j'ai bien compris fonctionnellement le problème, il s'agit de dédoublonnage, avec un critère "flou", la distance temporelle, ce qui pose le problème suivant (dasn lequel toutes les transactions ont le même triplet (idmembre, idpartenaire, montant)

    A à 6h00
    B à 6h04
    C à 6h08

    A est proche de B et B proche de C, mais A n'est pas proche de C : que faire ?

    Exemple simplifié si on considère que C doit être éliminé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT IdTransaction
    FROM   Transactions a
    WHERE  EXISTS (SELECT NULL 
                   FROM   Transactions b
                   WHERE  a.IdTransaction <> b.IdTransaction
                     AND  b.DateTransaction + (5 / (24*60)) >= a.DateTransaction
                     AND  b.DateTransaction <= a.DateTransaction);
    Note = + (5 / (24*60)) revient à ajouter 5 mn sous ORACLE

  7. #7
    Nouveau membre du Club
    Inscrit en
    Septembre 2005
    Messages
    44
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 44
    Points : 31
    Points
    31
    Par défaut
    Salut je n'ai pas réussi à insérer une image de ma table mais le lien ci dessous en montre un extrait. Je sais, c'est pourri mais j'ai pas de site perso.

    http://mandaillou.over-blog.com/phot...base1_jpg.html

    La premiere colonne numtransaction_jour est la clé primaire de la table.
    Dans cette table, les transactions 7 et 8 ont même montant, même idmembre et même idpartenaire et leur date de transaction est différente de moins de 5 minutes. C'est l'exemple type des transactions que je veux récupérer dans ma requête. Le but étant, à la fin, de ne garder qu'une seule des transactions en trop et de supprimer les autres après les avoir insérées dans une autre table, transactions_erronees.

    Voila, si vous avez encore des questions n'hésitez pas.

  8. #8
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    La requête que je t'ai donnée donne la liste des lignes qui sont à moins de 5 mn d'une précédente (celles à éliminer donc), bine sur, il faut l'adapter à ton cas particulier.

  9. #9
    Membre expert
    Avatar de TheLeadingEdge
    Inscrit en
    Mai 2005
    Messages
    1 199
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 1 199
    Points : 3 103
    Points
    3 103
    Par défaut
    Re,

    Citation Envoyé par mandaillou
    Le problème vient de la restriction sur la date
    Au vu de ta dernière réponse, non, le problème ne vient pas de la restriction sur la date. Tu fais ta jointure sur numtransaction_jour
    Citation Envoyé par mandaillou
    TP.numtransaction_jour=TD.numtransaction_jour
    or les lignes que tu veux grouper n'ont pas le même numtransaction_jour!

    Essaies-de faire ta jointure comme je te proposais ds mon premier post, en utilisant les champs membre, partenaire et montant.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    select count(*), 
    TP.idmembre,
    TP.montant,
    TP.id_partenaire  
    from transactions_jour TP 
    inner join transactions_jour TD 
    on TP.idmembre=TD.idmembre 
    and TP.id_partenaire  = TD.id_partenaire  
    and TP.montant = TD.montant
    where TP.datetransaction >= TD.datetransaction 
    and TP.datetransaction <= dateadd(minute,5,TD.datetransaction) 
    group by TP.idmembre,
    TP.montant,
    TP.id_partenaire 
    having count(*) > 1;
    A +

    [edit]Encore grillé...[/edit]

  10. #10
    Nouveau membre du Club
    Inscrit en
    Septembre 2005
    Messages
    44
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 44
    Points : 31
    Points
    31
    Par défaut
    Salut j'ai modifié ma requête, la voici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT Count(*) AS Expr1, TP.idmembre, TP.montant, TP.idpartenaire
    FROM transactions_jour AS TP INNER JOIN transactions_jour AS TD ON (TP.montant = TD.montant) AND (TP.idpartenaire = TD.idpartenaire) AND (TP.idmembre = TD.idmembre)
    WHERE (((TP.datetransaction)>=([TD].[datetransaction]) And (TP.datetransaction)<=DateAdd("n",1,([TD].[datetransaction]))))
    GROUP BY TP.idmembre, TP.montant, TP.idpartenaire
    HAVING (((Count(*))>1));
    Problème : elle me renvoie bien les transactions qui ont même idmembre, même idpartenaire et même montant mais elle ne tient pas compte des restrictions sur la date.
    J'ai testé la fonction dateadd, ça marche. J'ai aussi testé les opérateurs de comparaisons, ils marchent aussi. Je ne vois pas pourquoi ça ne marche pas.

    Merci

  11. #11
    Membre expert
    Avatar de TheLeadingEdge
    Inscrit en
    Mai 2005
    Messages
    1 199
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 1 199
    Points : 3 103
    Points
    3 103
    Par défaut
    Bonjour,

    Là tu me colle ... Je ne vois pas de raison pour que ça ne marche pas ...
    J'ai adapté 1 peu ta rq (juste la date en fait) pour DB2 (j'ai que ça sous la main pour le moment ...) et en la passant sur le jeu d'essai que tu as posté hier ça donne ça :

    select * from transactions_jour

    NUMTRANSACTION_JOUR MONTANT IDMEMBRE IDPARTENAIRE DATETRANSA
    CTION
    ------------------- ------------------------ ----------- ------------ ----------
    ----------------
    6 +4,12000000000000E+002 12 31 2005-10-01
    -10.51.44.000000
    7 +3,60000000000000E+001 12 31 2005-10-01
    -10.52.47.000000
    8 +3,60000000000000E+001 12 31 2005-10-01
    -10.53.22.000000
    9 +3,60000000000000E+001 8 158 2005-10-01
    -10.54.37.000000
    10 +2,40000000000000E+001 45 28 2005-10-01
    -10.56.07.000000
    999 +3,60000000000000E+001 12 31 2005-10-01
    -10.59.00.000000

    6 record(s) selected.


    SELECT Count(*) AS Expr1, TP.idmembre, TP.montant, TP.idpartenaire FROM transact
    ions_jour AS TP INNER JOIN transactions_jour AS TD ON (TP.montant = TD.montant)
    AND (TP.idpartenaire = TD.idpartenaire) AND (TP.idmembre = TD.idmembre) WHERE ((
    (TP.datetransaction)>=(TD.datetransaction) And (TP.datetransaction)<=(Td.datetra
    nsaction + 5 minutes))) GROUP BY TP.idmembre, TP.montant, TP.idpartenaire HAVING
    (((Count(*))>1))

    EXPR1 IDMEMBRE MONTANT IDPARTENAIRE
    ----------- ----------- ------------------------ ------------
    4 12 +3,60000000000000E+001 31

    1 record(s) selected.


    CONNECT RESET
    DB20000I The SQL command completed successfully.
    A +

  12. #12
    Nouveau membre du Club
    Inscrit en
    Septembre 2005
    Messages
    44
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 44
    Points : 31
    Points
    31
    Par défaut
    J'ai fait ça sous Access. Je verrais bien ce que ça donne au taff sous SQLserver.

  13. #13
    Nouveau membre du Club
    Inscrit en
    Septembre 2005
    Messages
    44
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 44
    Points : 31
    Points
    31
    Par défaut
    Voici la requete que j'utilise :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    select count(*), TP.idmembre, TP.montant, TP.id_partenaire, 
           min(TP.datetransaction) as minimum, max(TP.datetransaction) as maximum
      from transactions_jour TP inner join transactions_jour TD 
           on TP.idmembre=TD.idmembre and TP.montant=TD.montant
     where TP.datetransaction >= TD.datetransaction
       and TP.datetransaction <= dateadd(minute,8,TD.datetransaction)
    group by TP.idmembre,TP.montant,TP.id_partenaire
    having count(*) > 1
    Dans select, je récupère le minimum et le maximum de datetransaction et je peux voir que la restriction sur la date ne marche pas.
    Si quelqu'un a une idée, merci.

    [Edit by Xo]
    Requête mise en forme, merci de faire attention à ce point si vous voulez être aidé
    cf. Conseils... à lire avant de poster
    [/Edit by Xo]

  14. #14
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    1) Dans le ON je rajouterais l'égalité des partenaires
    2) Je calculerais le MIN et le MAX sur TD et non TP
    3) Le JOIN ne me paraît pas la meilleure solution dans ce cas à cause de ma remarque du Sam Oct 01, 2005 10:11
    4) As-tu essayé ma requête de ce même post ?

    Xo>> + 100 (j'ai dû faire un copier coller pour la formatter)

  15. #15
    Membre expert
    Avatar de TheLeadingEdge
    Inscrit en
    Mai 2005
    Messages
    1 199
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 1 199
    Points : 3 103
    Points
    3 103
    Par défaut
    Re,

    Dans le ON je rajouterais l'égalité des partenaires
    +1, je te l'avais mis ds mes posts précédents.
    Quoiqu'il en soit j'ai passé ta rq ds sql server et voila ce qu'elle me retourne :

    select count(*), TP.idmembre,TP.montant,TP.idpartenaire,min(TP.datetransaction)
    as minimum, max(TP.datetransaction) as maximum
    from DVP.dbo.transactions_jour TP inner join DVP.dbo.transactions_jour TD on TP.
    idmembre=TD.idmembre and TP.montant=TD.montant
    where (TP.datetransaction) >= (TD.datetransaction)
    and (TP.datetransaction) <= (dateadd(minute,5,TD.datetransaction))
    group by TP.idmembre,TP.montant,TP.idpartenaire
    having count(*) > 1

    idmembre montant idpartenaire
    minimum maximum
    ----------- ----------- ------------------------ ------------
    ----------------------- -----------------------
    4 12 36.0 31
    2005-10-01 10:52:47.000 2005-10-01 10:59:00.000

    (1 ligne affectée)
    : :

  16. #16
    Nouveau membre du Club
    Inscrit en
    Septembre 2005
    Messages
    44
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 44
    Points : 31
    Points
    31
    Par défaut
    Dans le ON je rajouterais l'égalité des partenaires
    Je l'avais oublié mais ça n'avait pas d'importance pour mon problème.

    J'ai trouvé le problème, il ne fallait pas mettre de = dans la comparaison de date sinon une date se recoupe avec elle même.

    Merci de votre aide.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. problème requête SQL
    Par soltani1 dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 11/05/2006, 23h36
  2. Problème requête SQL dans page ASP
    Par rocs dans le forum ASP
    Réponses: 14
    Dernier message: 26/07/2005, 15h38
  3. problème requête sql
    Par psychoBob dans le forum Langage SQL
    Réponses: 1
    Dernier message: 10/07/2005, 17h50
  4. problème requête sql
    Par perfectdams dans le forum Requêtes et SQL.
    Réponses: 5
    Dernier message: 21/06/2005, 18h09
  5. Réponses: 8
    Dernier message: 23/10/2003, 16h22

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo