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

Bases de données Delphi Discussion :

Multiple rows in singleton select


Sujet :

Bases de données Delphi

  1. #1
    Membre régulier
    Inscrit en
    Mars 2002
    Messages
    240
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 240
    Points : 102
    Points
    102
    Par défaut Multiple rows in singleton select
    bonjour,

    j'ai une requête de sélection qui plante avec le message "Multiple rows in singleton select". Elle est compliquée, si quelq'un peut m'aider car je ne sais pas trop comment faire
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    select cast(floatdiv(sum((select J.INV_PRIXUNITE *(floatdiv(UTJ_QTETOTJOUR1, 1)
     + floatdiv(UTJ_QTETOTJOUR2, 1) + floatdiv(UTJ_QTETOTJOUR3, 1) + floatdiv(
     UTJ_QTETOTJOUR4, 1) + floatdiv(UTJ_QTETOTJOUR5, 1) + floatdiv(UTJ_QTETOTJOUR6,
      1) + floatdiv(UTJ_QTETOTJOUR7, 1) + floatdiv(UTJ_QTETOTJOUR8, 1) + floatdiv(
      UTJ_QTETOTJOUR9, 1) + floatdiv(UTJ_QTETOTJOUR10, 1) + floatdiv(
      UTJ_QTETOTJOUR11, 1) + floatdiv(UTJ_QTETOTJOUR12, 1) + floatdiv(
      UTJ_QTETOTJOUR13, 1) + floatdiv(UTJ_QTETOTJOUR14, 1) + floatdiv(
      UTJ_QTETOTJOUR15, 1) + floatdiv(UTJ_QTETOTJOUR16, 1) + floatdiv(
      UTJ_QTETOTJOUR17, 1) + floatdiv(UTJ_QTETOTJOUR18, 1) + floatdiv(
      UTJ_QTETOTJOUR19, 1) + floatdiv(UTJ_QTETOTJOUR20, 1) + floatdiv(
      UTJ_QTETOTJOUR21, 1) + floatdiv(UTJ_QTETOTJOUR22, 1) + floatdiv(
      UTJ_QTETOTJOUR23, 1) + floatdiv(UTJ_QTETOTJOUR24, 1) + floatdiv(
      UTJ_QTETOTJOUR25, 1) + floatdiv(UTJ_QTETOTJOUR26, 1) + floatdiv(
      UTJ_QTETOTJOUR27, 1) + floatdiv(UTJ_QTETOTJOUR28, 1) + floatdiv(
      UTJ_QTETOTJOUR29, 1) + floatdiv(UTJ_QTETOTJOUR30, 1) + floatdiv(
      UTJ_QTETOTJOUR31, 1)) from INVUTILISATIONJOUR U where UTJ_ANNEE * 12 +
       UTJ_MOIS > 24132 and UTJ_ANNEE * 12 + UTJ_MOIS < 24136 and U.PRB_CODWRIN =
        B.PRB_CODWRIN)), 1) as NUMERIC (12, 3)) PRIX_QTETOT
    from HISPRODBRUT B2,
         INVPRODGENERIQUE G,
         HISPRODBRUT B
         left join INVINVENTAIRE J on (J.PRB_CODWRIN = B.PRB_CODWRIN and
          J.CAL_DTACTIVITE = '4/14/2011')
         left join INVNIVEAUSTOCK K on (K.PRB_CODWRIN = B.PRB_CODWRIN and
          K.NST_ANNEE = 2010 and K.NST_MOIS = 12)
    where B.PRB_DTEFFET <= '4/14/2011' and
          (B.PRB_DTFINEFFET >= '4/14/2011' or
          B.PRB_DTFINEFFET is null) and
          B.PRB_ACTIF = 'T' and
          B.PRB_PERIODEINV <= 0 and
          B.PRG_CODMRIN = G.PRG_COD and
          G.PRB_CODCALCULCOUT = B2.PRB_CODWRIN and
          G.PRG_RENDSTAT = 'T' and
          B2.PRB_DTEFFET <= '4/14/2011' and
          (B2.PRB_DTFINEFFET >= '4/14/2011' or
          B2.PRB_DTFINEFFET is null)
    group by B.PRG_CODMRIN

  2. #2
    Membre régulier
    Inscrit en
    Mars 2002
    Messages
    240
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 240
    Points : 102
    Points
    102
    Par défaut
    remarque : c'est la jointure à gauche avec J qui pose problème car si je remplace
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    left join INVINVENTAIRE J
    par le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    inner join INVINVENTAIRE J
    ça passe ... j'ai alors 0 enregistrement !

  3. #3
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Left Join te permet d'avoir tous les enregistrements trouvés pour la jointure entre HISPRODBRUT, INVPRODGENERIQUE et HISPRODBRUT
    les champs des tables INVINVENTAIRE et INVNIVEAUSTOCK seront mis à NULL pour les lignes manquantes !

    SUM est-il au bon endroit ?
    Je l'aurais mis dans la sous-requête !

    GROUP BY ne contient qu'un seul champ est-ce suffisant ?

    Tu devrais utiliser une table temporaire pour écrire tes calculs de INVUTILISATIONJOUR puis faire le SUM sur cette table temporaire
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  4. #4
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Salut

    Multiple rows in singleton select
    Cette requête est dans une procédure stockée, non ?

    Ce message d'erreur se produit lorsque que la requête renvoie plus d'un enregistrement.
    La clause "INTO :variable" qui suit cette requête échoue car on ne peut stocker plusieurs valeurs dans une variable.

    Ta clause GROUP BY ne garantie pas l'unicité du résultat, et heureusement d'ailleurs.

    Question:
    Quel calcul effectue l'UDF FloatDiv ? Est-elle nécessaire ?
    Dans 90% des cas on peut se passer des UDFs.
    Il faut que tu saches que cette requête va sollicité 31 fois par enregistrement la DLL.

    Ton SGBD (Firebird il me semble) est parfaitement capable d'effectuer une division et d'en arrondir le résultat si besoin.

    Autre remarque:
    Tes jointures sont peu courantes, d'une part tu utilises LEFT|INNER JOIN et d'autre part tu définis ces jointures "à l'ancienne" dans la clause WHERE.
    Sépare bien la jointure en elle-même et tes conditions de filtres.

    @+ Claudius.

  5. #5
    Membre régulier
    Inscrit en
    Mars 2002
    Messages
    240
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 240
    Points : 102
    Points
    102
    Par défaut
    si je met le SUM à l'intérieur du 2ème SELECT ça marche à condition de supprimer la clause GROUP BY finale

    maintenant je dois rajouter au 1er SELECT un autre champ :
    MAX(B2.PRB_SEQUENCE) TRI_SEQUENCE
    cela donne donc :
    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    SELECT 
    MAX(B2.PRB_SEQUENCE) TRI_SEQUENCE,
    cast(floatdiv((SELECT sum(J.INV_PRIXUNITE *(floatdiv(UTJ_QTETOTJOUR1, 1)
     + floatdiv(UTJ_QTETOTJOUR2, 1) + floatdiv(UTJ_QTETOTJOUR3, 1) + floatdiv(
     UTJ_QTETOTJOUR4, 1) + floatdiv(UTJ_QTETOTJOUR5, 1) + floatdiv(UTJ_QTETOTJOUR6,
      1) + floatdiv(UTJ_QTETOTJOUR7, 1) + floatdiv(UTJ_QTETOTJOUR8, 1) + floatdiv(
      UTJ_QTETOTJOUR9, 1) + floatdiv(UTJ_QTETOTJOUR10, 1) + floatdiv(
      UTJ_QTETOTJOUR11, 1) + floatdiv(UTJ_QTETOTJOUR12, 1) + floatdiv(
      UTJ_QTETOTJOUR13, 1) + floatdiv(UTJ_QTETOTJOUR14, 1) + floatdiv(
      UTJ_QTETOTJOUR15, 1) + floatdiv(UTJ_QTETOTJOUR16, 1) + floatdiv(
      UTJ_QTETOTJOUR17, 1) + floatdiv(UTJ_QTETOTJOUR18, 1) + floatdiv(
      UTJ_QTETOTJOUR19, 1) + floatdiv(UTJ_QTETOTJOUR20, 1) + floatdiv(
      UTJ_QTETOTJOUR21, 1) + floatdiv(UTJ_QTETOTJOUR22, 1) + floatdiv(
      UTJ_QTETOTJOUR23, 1) + floatdiv(UTJ_QTETOTJOUR24, 1) + floatdiv(
      UTJ_QTETOTJOUR25, 1) + floatdiv(UTJ_QTETOTJOUR26, 1) + floatdiv(
      UTJ_QTETOTJOUR27, 1) + floatdiv(UTJ_QTETOTJOUR28, 1) + floatdiv(
      UTJ_QTETOTJOUR29, 1) + floatdiv(UTJ_QTETOTJOUR30, 1) + floatdiv(
      UTJ_QTETOTJOUR31, 1))) FROM INVUTILISATIONJOUR U WHERE UTJ_ANNEE * 12 +
       UTJ_MOIS > 24132 AND UTJ_ANNEE * 12 + UTJ_MOIS < 24136 AND U.PRB_CODWRIN =
        B.PRB_CODWRIN), 1) AS NUMERIC (12, 3)) PRIX_QTETOT
    FROM HISPRODBRUT B2,
         INVPRODGENERIQUE G,
         HISPRODBRUT B
         LEFT JOIN INVINVENTAIRE J ON (J.PRB_CODWRIN = B.PRB_CODWRIN AND
          J.CAL_DTACTIVITE = '4/14/2011')
         LEFT JOIN INVNIVEAUSTOCK K ON (K.PRB_CODWRIN = B.PRB_CODWRIN AND
          K.NST_ANNEE = 2010 AND K.NST_MOIS = 12)
    WHERE B.PRB_DTEFFET <= '4/14/2011' AND
          (B.PRB_DTFINEFFET >= '4/14/2011' OR
          B.PRB_DTFINEFFET IS NULL) AND
          B.PRB_ACTIF = 'T' AND
          B.PRB_PERIODEINV <= 0 AND
          B.PRG_CODMRIN = G.PRG_COD AND
          G.PRB_CODCALCULCOUT = B2.PRB_CODWRIN AND
          G.PRG_RENDSTAT = 'T' AND
          B2.PRB_DTEFFET <= '4/14/2011' AND
          (B2.PRB_DTFINEFFET >= '4/14/2011' OR
          B2.PRB_DTFINEFFET IS NULL)
    nouveau message d'erreur :
    Invalid expression in the select list (not contained in either an aggregate function or the GROUP BY clause).
    j'ai rajouter donc rajouter une clause GROUP BY PRIX_QTETOT et là encore un autre message d'erreur :
    Cannot use an aggregate function in a GROUP BY clause.
    comment faire ?

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Citation Envoyé par jakouz Voir le message
    si je met le SUM à l'intérieur du 2ème SELECT ...
    Ta Requête est très compliqué et ton modèle de DB semble assez "pourri"
    Je ne sais pas ce que tu essaye de calculer mais ça semble tordu !
    Tu pars sur un SUM de 31 colonnes, comme déjà par cela !
    Sans sous-requête !

    floatdiv(?, 1) me dit pas que cela divise par 1 ! ? ça sert à quoi ?

    tu as une façon de penser assez étrange !
    Rien que dans ta façon d'écrire des calculs sur les dates !

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ... WHERE UTJ_ANNEE * 12 +
       UTJ_MOIS > 24132 AND UTJ_ANNEE * 12 + UTJ_MOIS < 24136 AND ...
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    ... WHERE UTJ_ANNEE = 2011 AND UTJ_MOIS BETWEEN 1 AND 3 AND ...

    HISPRODBRUT apparait deux fois dans la requête, c'est très étrange !

    UTJ_QTETOTJOUR1 sont dans INVNIVEAUSTOCK ou INVINVENTAIRE ?
    si dans INVINVENTAIRE alors INVNIVEAUSTOCK ne sert à rien puisque Letf Join !
    ajoute K ou J devans UTJ_QTETOTJOUR1, pour s'y retrouver !


    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    SELECT 
      SUM(
        UTJ_QTETOTJOUR1 + 
        UTJ_QTETOTJOUR2 + 
        UTJ_QTETOTJOUR3 + 
        UTJ_QTETOTJOUR4 + 
        UTJ_QTETOTJOUR5 + 
        UTJ_QTETOTJOUR6 + 
        UTJ_QTETOTJOUR7 + 
        UTJ_QTETOTJOUR8 + 
        UTJ_QTETOTJOUR9 + 
        UTJ_QTETOTJOUR10 + 
        UTJ_QTETOTJOUR11 + 
        UTJ_QTETOTJOUR12 + 
        UTJ_QTETOTJOUR13 + 
        UTJ_QTETOTJOUR14 + 
        UTJ_QTETOTJOUR15 + 
        UTJ_QTETOTJOUR16 + 
        UTJ_QTETOTJOUR17 + 
        UTJ_QTETOTJOUR18 + 
        UTJ_QTETOTJOUR19 + 
        UTJ_QTETOTJOUR20 + 
        UTJ_QTETOTJOUR21 + 
        UTJ_QTETOTJOUR22 + 
        UTJ_QTETOTJOUR23 + 
        UTJ_QTETOTJOUR24 + 
        UTJ_QTETOTJOUR25 + 
        UTJ_QTETOTJOUR26 + 
        UTJ_QTETOTJOUR27 + 
        UTJ_QTETOTJOUR28 + 
        UTJ_QTETOTJOUR29 + 
        UTJ_QTETOTJOUR30 + 
        UTJ_QTETOTJOUR31
      ) as __QTETOTMOIS,
      __QTETOTMOIS * J.INV_PRIXUNITE AS PRIX_QTETOT
    FROM INVUTILISATIONJOUR U 
      INNER JOIN HISPRODBRUT B ON (U.PRB_CODWRIN = B.PRB_CODWRIN) 
      INNER JOIN INVPRODGENERIQUE G ON (B.PRG_CODMRIN = G.PRG_COD AND G.PRB_CODCALCULCOUT = B.PRB_CODWRIN AND G.PRG_RENDSTAT = 'T') 
     
      LEFT JOIN INVINVENTAIRE J ON (J.PRB_CODWRIN = B.PRB_CODWRIN AND J.CAL_DTACTIVITE = '4/14/2011')
      LEFT JOIN INVNIVEAUSTOCK K ON (K.PRB_CODWRIN = B.PRB_CODWRIN AND K.NST_ANNEE = 2010 AND K.NST_MOIS = 12)
     
    WHERE UTJ_ANNEE * 12 + UTJ_MOIS > 24132 AND UTJ_ANNEE * 12 + UTJ_MOIS < 24136
      AND B.PRB_DTEFFET <= '4/14/2011' AND
        (B.PRB_DTFINEFFET >= '4/14/2011' OR B.PRB_DTFINEFFET IS NULL) AND
        B.PRB_ACTIF = 'T' AND
        B.PRB_PERIODEINV <= 0
     
    GROUP BY B.PRG_CODMRIN
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  7. #7
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    floatdiv(?, 1) me dit pas que cela divise par 1 ! ? ça sert à quoi ?
    C'est bien la question que je me pose, et j'espère que ça ne se limite pas à diviser par par 1.

    @jakouz
    Je vais te donner le même conseil que Shai: procède par étape et par ajout successif de Tables/Champs ce qui te permettra d'isoler pourquoi tu te retrouves avec plusieurs enregistrements.

    @+

  8. #8
    Membre régulier
    Inscrit en
    Mars 2002
    Messages
    240
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 240
    Points : 102
    Points
    102
    Par défaut
    merci à vous La requête n'est pas de moi ! je vais voir ce que je peux faire ...

Discussions similaires

  1. multiple rows in singleton select.
    Par le_dilem dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 20/07/2009, 14h02
  2. erreur multiple rows in singleton select
    Par bassim dans le forum SQL
    Réponses: 5
    Dernier message: 20/12/2006, 16h56
  3. pb : multiple rows in singleton select
    Par sillycoder dans le forum SQL
    Réponses: 6
    Dernier message: 12/06/2005, 16h35
  4. Réponses: 3
    Dernier message: 25/01/2005, 12h31
  5. Mutiple row in singleton select ????? [Important, merci]
    Par SkyDev dans le forum Bases de données
    Réponses: 6
    Dernier message: 20/04/2004, 14h02

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