Partage
  • Partager sur Facebook
  • Partager sur Twitter

Traitement sous requête avec plusieurs lignes

SQL0811 : Résultat de SELECT dépasse une ligne.

    29 mai 2020 à 10:18:29

    Hello,

    j'ai ce problème qui me bloque et je n'arrive pas à trouver une solution.

    J'ai une requete select avec plusierus sous-requetes. Je peux pas avoir un résultat puisque j'ai plusieurs lignes dupliqué dans les sous-requetes et d'aprés le msg d'erreur, une seule ligne est admise.

    voici ma requete :

    SELECT  A.DTNUMEXE, A.DTMOIEXE, A.DTANNQIT, A.DTMOIQIT, A.DTCODBRC, A.DTSERQIT, A.DTPLCQTC,A.DTCATPOL, A.DTCODRSQ, A.DTNATRSQ, A.DTCODPRO, A.DTTYPQIT, A.DTLIBTYP, A.DTCODETA, 

            A.DTLIBETA, A.DTCODAGC, A.DTNUMCLT, A.DTNATCLT, A.DTJJDVAL, A.DTMMDVAL, A.DTAADVAL,A.DTJJFVAL, A.DTMMFVAL, A.DTAAFVAL, A.DTCODART, A.DTCODGRN, A.DTPRMNET, A.DTMNTACC, 

            A.DTJJEMIS, A.DTMMEMIS, A.DTAAEMIS, CASE WHEN A.DTNUMCLT >= 50000 AND A.DTNUMCLT <= 100000 THEN 'OUI' ELSE 'NON' END  DTCLTIMP,               

            CASE UPPER(A.DTPLCEXO) WHEN 'O' THEN 'OUI' WHEN 'N' THEN 'NON' END  DTEXOTAX, A.DTMNTCOM ,

    (SELECT X.VGFRNNBP FROM   AUTOPRD.AUVCLGRPP0  AS X where (X.VGNUMPLC = A.DTPLCQTC )  AND (X.VGCODGRN=  A.DTCODGRN) 

    AND (X.VGJJOCCU * 1000000 + X.VGMMOCCU * 100000000 + X.VGAAOCCU * 10000000000 + X.VGNUMAVT) IN (SELECT  MAX(X.VGJJOCCU * 1000000 + X.VGMMOCCU * 100000000 + X.VGAAOCCU * 10000000000 + X.VGNUMAVT ) AS DATEOCC FROM AUTOPRD.AUVCLGRPP0

    WHERE     (X.VGMMOCCU * 100000000 + X.VGAAOCCU * 10000000000 <= (A.DTAADVAL * 10000 + A.DTMMDVAL * 100 + A.DTJJDVAL)*1000000 )  AND (X.VGNUMPLC =A.DTPLCQTC) AND (X.VGCODGRN=  A.DTCODGRN))),

    (SELECT  X.VGCPTPTN FROM   AUTOPRD.AUVCLGRPP0  AS X where (X.VGNUMPLC = A.DTPLCQTC )  AND (X.VGCODGRN=  A.DTCODGRN) 

    AND (X.VGJJOCCU * 1000000 + X.VGMMOCCU * 100000000 + X.VGAAOCCU * 10000000000 + X.VGNUMAVT) IN  (SELECT  MAX(X.VGJJOCCU * 1000000 + X.VGMMOCCU * 100000000 + X.VGAAOCCU * 10000000000 + X.VGNUMAVT ) AS DATEOCC FROM AUTOPRD.AUVCLGRPP0

    WHERE     (X.VGMMOCCU * 100000000 + X.VGAAOCCU * 10000000000 <= (A.DTAADVAL * 10000 + A.DTMMDVAL * 100 + A.DTJJDVAL)*1000000 )  AND (X.VGNUMPLC =A.DTPLCQTC) AND (X.VGCODGRN=  A.DTCODGRN)) )

    FROM TRANSFERT.DTQTTNCPP1 AS A

    WHERE   (A.DTCODBRC = 1) AND  (A.DTCODGRN>0)   AND  (DTNUMEXE =2020) 

    -
    Edité par houssemeddineayari 29 mai 2020 à 12:04:22

    • Partager sur Facebook
    • Partager sur Twitter
      29 mai 2020 à 13:58:37

      Bonjour,

      Dans un premier temps, organise ton code, et accessoirement tu pouvais le poster avec la balise code (le bouton </> de l'éditeur de message), et ça donne ça :

      SELECT
      	A.DTNUMEXE,
      	A.DTMOIEXE,
      	A.DTANNQIT,
      	A.DTMOIQIT,
      	A.DTCODBRC,
      	A.DTSERQIT,
      	A.DTPLCQTC,
      	A.DTCATPOL,
      	A.DTCODRSQ,
      	A.DTNATRSQ,
      	A.DTCODPRO,
      	A.DTTYPQIT,
      	A.DTLIBTYP,
      	A.DTCODETA, 
      	A.DTLIBETA,
      	A.DTCODAGC,
      	A.DTNUMCLT,
      	A.DTNATCLT,
      	A.DTJJDVAL,
      	A.DTMMDVAL,
      	A.DTAADVAL,
      	A.DTJJFVAL,
      	A.DTMMFVAL,
      	A.DTAAFVAL,
      	A.DTCODART,
      	A.DTCODGRN,
      	A.DTPRMNET,
      	A.DTMNTACC, 
      	A.DTJJEMIS,
      	A.DTMMEMIS,
      	A.DTAAEMIS,
      	CASE WHEN A.DTNUMCLT >= 50000 AND A.DTNUMCLT <= 100000 THEN 'OUI' ELSE 'NON' END DTCLTIMP,               
      	CASE UPPER( A.DTPLCEXO ) WHEN 'O' THEN 'OUI' WHEN 'N' THEN 'NON' END  DTEXOTAX,
      	A.DTMNTCOM,
      	(
      		SELECT X.VGFRNNBP
      		FROM AUTOPRD.AUVCLGRPP0 AS X
      		WHERE
      			X.VGNUMPLC = A.DTPLCQTC 
      			AND X.VGCODGRN = A.DTCODGRN
      			AND ( X.VGJJOCCU * 1000000 + X.VGMMOCCU * 100000000 + X.VGAAOCCU * 10000000000 + X.VGNUMAVT ) IN (
      				SELECT  MAX(X.VGJJOCCU * 1000000 + X.VGMMOCCU * 100000000 + X.VGAAOCCU * 10000000000 + X.VGNUMAVT ) AS DATEOCC
      				FROM AUTOPRD.AUVCLGRPP0
      				WHERE
      					( X.VGMMOCCU * 100000000 + X.VGAAOCCU * 10000000000 <= ( A.DTAADVAL * 10000 + A.DTMMDVAL * 100 + A.DTJJDVAL )*1000000 ) 
      					AND X.VGNUMPLC = A.DTPLCQTC
      					AND X.VGCODGRN = A.DTCODGRN
      			)
      	),
      	(
      		SELECT X.VGCPTPTN
      		FROM AUTOPRD.AUVCLGRPP0 AS X
      		WHERE
      			X.VGNUMPLC = A.DTPLCQTC
      			AND X.VGCODGRN = A.DTCODGRN 
      			AND ( X.VGJJOCCU * 1000000 + X.VGMMOCCU * 100000000 + X.VGAAOCCU * 10000000000 + X.VGNUMAVT ) IN (
      				SELECT  MAX(X.VGJJOCCU * 1000000 + X.VGMMOCCU * 100000000 + X.VGAAOCCU * 10000000000 + X.VGNUMAVT ) AS DATEOCC
      				FROM AUTOPRD.AUVCLGRPP0
      				WHERE
      					( X.VGMMOCCU * 100000000 + X.VGAAOCCU * 10000000000 <= ( A.DTAADVAL * 10000 + A.DTMMDVAL * 100 + A.DTJJDVAL )*1000000 ) 
      					AND X.VGNUMPLC = A.DTPLCQTC
      					AND X.VGCODGRN = A.DTCODGRN
      			)
      	)
      FROM TRANSFERT.DTQTTNCPP1 AS A
      WHERE
      	A.DTCODBRC = 1
      	AND A.DTCODGRN > 0
      	AND DTNUMEXE = 2020

      C'est bien plus simple à lire et à comprendre, pour toi comme pour les autres ...

      Ensuite, il est fortement déconseillé de faire des SELECT imbriqués ! Ceux-ci sont réévalués pour chaque ligne de la requête principale ... si tu as beaucoup d'enregistrements les temps de réponse vont exploser ...

      Il est préférable de mettre tes sous-requêtes dans le FROM ce qui aura en plus l'avantage de résoudre ton erreur et de mettre le nez sur le problème : il y a plusieurs lignes avec le même MAX ...

      houssemeddineayari a écrit:

      j'ai plusieurs lignes dupliqué dans les sous-requetes et d'aprés le msg d'erreur, une seule ligne est admise

      C'est normal, sur une ligne de résultat tu ne peux pas afficher plusieurs autres lignes ...

      Maintenant, il est impossible de t'aider sans connaître le modèle de données, les relations et les cardinalités ... Si tu ne sais pas pourquoi tes sous-requêtes retournent plusieurs lignes c'est que tu ne connais pas toi-même le modèle ... et que tu essayes de consolider des données que tu ne comprends pas ...

      Peux-tu nous expliquer de quels types de données l'on parle ici, à quoi sert le MAX et le sens de la requête ?

      -
      Edité par Benzouye 29 mai 2020 à 13:59:43

      • Partager sur Facebook
      • Partager sur Twitter
      Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
        29 mai 2020 à 14:06:40

        Bonjour , 

        en fait c'est un nouveau projet et le principe c'est d'abord de rendre l'import des données pendant les années dynamique pour l'ETL et optimiser le temps d’exécution des requets .

        C'est la requete source; puisque il y a plus de 28 million de lignes et il y a le composant script utilisé dans l'ETL qui traite les données ligne par ligne, j'ai essayé de modifier la requete source en faisant appel à tous les tables dans la source et faire le nécessaire. (On parle pas de cardinalité sous SSIS)

        C'est un exemple de jointure puisque j'ai plus de 13 jointures; j'essaye de séléctioner plusieurs colonnes de la table principale TRANSFERT.DTQTTNCPP1 et faire les relations avec les autres tables. J'utilise les sous-requetes (requetes imbriquées) car si je les mets aprés le from TRANSFERT.DTQTTNCPP1 ça prends plus de temps (c'est vérifié).

        Le MAX puisque j'ai plusieurs lignes dupliqués avec des dates différents, je fait appel au MAX à la date d’occurrence de chaque ligne. L'erreur que j'ai qu'avec les requetes imbriquées une seule ligne est admise. Donc j'ai testé avec top et limit et avec limit1 c'est correct.

        -
        Edité par houssemeddineayari 29 mai 2020 à 14:19:14

        • Partager sur Facebook
        • Partager sur Twitter
          29 mai 2020 à 14:32:02

          houssemeddineayari a écrit:

          si je les mets aprés le from TRANSFERT.DTQTTNCPP1 ça prends plus de temps (c'est vérifié)

          C'est n'importe quoi cette histoire ... C'est que les conditions de jointures ne sont pas bonnes ...

          houssemeddineayari a écrit:

          On parle pas de cardinalité sous SSIS

          On parle de cardinalités dans toutes relations entre deux tables ... une cardinalités c'est combien d'enregistrements d'une table sont liés à une autre pour une valeur unique d'un côté ...

          houssemeddineayari a écrit:

          avec limit1 c'est correct

          Si tu prends LIMIT 1 tu pers des informations ... et tu récupères (dans l'exemple) un seul VGCPTPTN là où plusieurs correspondent ... ou alors c'est qu'un DISTINCT aurait suffit, mais là encore c'est que tu ne connais pas le modèle et son fonctionnement, et que ce que tu cherches à consolider n'est pas cohérent ...

          • Partager sur Facebook
          • Partager sur Twitter
          Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
            1 juin 2020 à 9:55:24

            Bonjour,

            Houssemeddineayari a écrit:

            On parle pas de cardinalité sous SSIS

            J récupére les données de l'AS400 et il sagit pas d'un table pour parler de cardinalités. Oui je comprends qu'il des relation entre les tables mais on n'a pas des clés uniques.

            avec limit1 c'est correct

            Voilà, je veux prendre un ligne car il y a plusieurs lignes dupliqué mais ça dépends d'autres colonnes ( c'est pourquoi j'utilise le MAX pour l’occurrence)



            • Partager sur Facebook
            • Partager sur Twitter

            Traitement sous requête avec plusieurs lignes

            × 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