J'ai une table de base de données avec les colonnes DOC1, DOC2 et CLIENT. J'essaie de sélectionner une ligne par CLIENT, dont la colonne DOC1 a la priorité la plus élevée en fonction de l'ordre suivant, de la priorité la plus élevée à la plus basse: ITCI> ITPP> ITPS> ITPT.
Voici un exemple.
Select single doc1 doc2 (W_doc1, W_doc2) FROM /BI0/Pdoctax WHERE client eq <RESULT_FIELDS>-client.
OUTPUT^
La table de destination doit avoir CLIENT a une clé unique et je dois ajouter les deux colonnes DOC1 et DOC2, en prenant la ligne qui a DOC1 avec la priorité la plus élevée.
CLIENT DOC2 DOC1 101 GG319 ITCI 102 YB311 ITPP
J'ai écrit un single select in end routine mais il y avait une erreur de syntaxe:
DOC1 DOC2 CLIENT ITCI GG319 101 ITPS YB311 102 ITPT GG319 101 ITPP YB311 102
4 Réponses :
Si je comprends bien, vous voulez que la sélection ne génère qu'une une ligne par CLIENT, en choisissant la ligne dans le tableau d'origine en fonction de ces priorités DOC1.
Une telle sélection n'est pas possible.
Au sommet de ma tête, ce sont les possibilités que je propose, mais il y en a probablement d'autres. En fonction de votre situation, vous devrez déterminer lequel correspond le mieux à vos besoins.
Vous pouvez tout sélectionner, BOUCLER dessus et créer votre format avec des conditions IF, etc.
Si vous n'avez vraiment que ces 4 possibilités DOC1, vous pouvez tout sélectionner, trier la table interne par CLIENT et DOC1, puis supprimer les doublons adjacents en comparant uniquement CLIENT. Cela fonctionnerait car "ITCI> ITPP> ITPS> ITPT" est dans l'ordre alphabétique.
Encore une fois, si vous n'avez que ces 4 possibilités DOC1, vous pouvez les sélectionner l'une après l'autre, en vérifiant s'il y a encore des CLIENTS manquants.
salut Legix, «Si je comprends bien, vous voulez que la sélection ne produise qu'une seule ligne par CLIENT, en choisissant la ligne de la table d'origine en fonction de ces priorités DOC1.» «Oui, j'essaie de le faire. pouvez-vous m'aider avec du code j'ai 6 types de doc1
Comme votre ordre de priorité du plus élevé au plus bas ressemble entièrement à l'ordre alphabétique, vous n'avez besoin de rien de plus que d'utiliser GROUP BY avec une agrégation MIN:
SELECT client, MIN( doc2 ) AS doc2, MIN( doc1 ) AS doc1 INTO TABLE @DATA(itab) FROM /BI0/Pdoctax GROUP BY client.
Dans les cas plus complexes où le classement n'est pas aussi primitif, vous pouvez utiliser la clause CASE
.
Je pense que l'OP ne veut pas de MIN (DOC2), il veut la valeur DOC2 qui correspond à la ligne qui contient la valeur minimale de DOC1 pour le client donné
Je ne sais pas, mais la sortie ressemble exactement à ce que vous souhaitez. Peut-être que sur des chaînes de priorité plus complexes, cela échouera, mais pour le cas ci-dessus, cela fonctionne
Étant donné que vos valeurs de priorité doc1 sont en fait de six, cela devrait fonctionner.
DATA lt_priorities TYPE STANDARD TABLE OF /bi0/pdoctax-doc1. lt_priorities = VALUE #( ( 'ITCI' ) ( 'ITPS' ) ( 'ITPT' ) ( 'ITPP' ) ( 'P500' ) ( 'P600' ) ). SELECT b~client, doc1, doc2 FROM /bi0/pdoctax AS b WHERE b~client = @<result_fields>-client ORDER BY doc1 ASCENDING INTO TABLE @DATA(lt_doctax). DATA ls_doctax_filtered LIKE LINE OF lt_doctax. LOOP AT lt_priorities ASSIGNING FIELD-SYMBOL(<fs_priority>). READ TABLE lt_doctax ASSIGNING FIELD-SYMBOL(<fs_doctax>) WITH KEY doc1 = <fs_priority> BINARY SEARCH. IF sy-subrc = 0. ls_doctax_filtered = <fs_doctax>. * ---> EXIT. ENDIF. ENDLOOP.
Je suppose que vous recherchez une réponse qui fait cela dans une seule instruction SELECT, sinon vous pouvez boucler:
SELECT b~client, coalesce( p1~doc1, p2~doc1, p3~doc1, p4~doc1, p5~doc1, p6~doc1 ), coalesce( p1~doc2, p2~doc2, p3~doc2, p4~doc2, p5~doc2, p6~doc2 ) FROM /bi0/pdoctax AS b LEFT OUTER JOIN /bi0/pdoctax AS p1 ON p1~client = b~client AND p1~doc1 = 'ITCI' LEFT OUTER JOIN /bi0/pdoctax AS p2 ON p2~client = b~client AND p2~doc1 = 'ITPS' LEFT OUTER JOIN /bi0/pdoctax AS p3 ON p3~client = b~client AND p3~doc1 = 'ITPT' LEFT OUTER JOIN /bi0/pdoctax AS p4 ON p4~client = b~client AND p4~doc1 = 'ITPT' LEFT OUTER JOIN /bi0/pdoctax AS p5 ON p4~client = b~client AND p4~doc1 = 'P5' LEFT OUTER JOIN /bi0/pdoctax AS p6 ON p4~client = b~client AND p4~doc1 = 'P6' WHERE b~client = @<result_fields>-client INTO @DATA(ls_doctax).
Voici une solution "simple" avec ABAP 7.52.
J'ai utilisé un autre exemple pour les tests afin que tout le monde puisse jouer avec: j'ai utilisé la table de démonstration SFLIGHT
qui est fournie avec tout Installation ABAP. Exécutez le programme SAPBC_DATA_GENERATOR
pour générer des données si la table est vide.
Comme déjà mentionné par d'autres personnes, il est supposé que votre priorité est basée sur l'ordre alphabétique, donc la fonction d'agrégation MIN
peut être utilisé.
Le code ci-dessous obtient les lignes de SFLIGHT
qui correspond à chaque valeur distincte de la colonne CARRID (équivalent à CLIENT dans votre question ) et sa valeur minimale dans la colonne PAYMENTSUM (DOC1) (les deux dans la sous-requête EXISTS
):
SELECT carrid, fldate AS doc2, paymentsum AS doc1 FROM sflight AS a WHERE EXISTS ( SELECT carrid FROM sflight WHERE carrid = a~carrid GROUP BY carrid HAVING MIN( paymentsum ) = a~paymentsum ) INTO TABLE @DATA(itab).
Contenu de la table de base de données SFLIGHT
(via SE16 / résultat attendu mis en évidence):
Contenu de la table interne itab
(via debug / comme prévu):
Remarque sur le code SQL ABAP:
SFLIGHT
ont les mêmes valeurs pour CARRID et PAYMENTSUM, alors l'une de ces lignes est sélectionnée au hasard (règle SQL classique). SELECT ... FROM (SELECT ...)
(non autorisé jusqu'à ABAP SQL 7.53)
DOC2 n'a pas de règles maintenant, pouvez-vous nous dire ce dont vous avez besoin?