J'ai besoin d'obtenir les lignes avec les registres EXBEL les plus élevés à partir d'une table interne pour chaque VKONT différent .
La table de résultats peut contenir plusieurs lignes pour le même Valeur VKONT si cette dernière a plusieurs lignes dans la table source avec la même valeur EXBEL la plus élevée.
Table source réelle:
SPARTE VKONT EXBEL 05 800000008422 1NSN150900000058 L2 800000008422 1NSN150900000058 05 800000008415 1HSN151200000012 S1 800000008415 1HSN151200000012
Table de résultats attendus:
SPARTE VKONT EXBEL 05 800000008422 1NSN150900000058 L2 800000008422 1NSN150900000058 05 800000008422 1NSN150900000037 L2 800000008422 1NSN150900000037 05 800000008422 1NSN150900000013 L2 800000008422 1NSN150900000013 05 800000008415 1HSN151200000009 S1 800000008415 1HSN151200000009 05 800000008415 1HSN151200000008 S1 800000008415 1HSN151200000008 L1 800000008422 1NSN150900000050 L1 800000008422 1NSN150900000029 L1 800000008422 1NSN150900000023 05 800000008415 1HSN151200000012 S1 800000008415 1HSN151200000012 05 800000008422 1NSN150900000058 L2 800000008422 1NSN150900000058 05 800000008415 1HSN151200000009 S1 800000008415 1HSN151200000009
J'ai essayé différentes solutions mais je n'ai pas fonctionné.
Toute aide sera appréciée.
Raúl. p >
4 Réponses :
Vous pouvez utiliser un TRIER
suivi d'un DELETE ADJACENT DUPLICATES
car ce dernier supprimera toutes les lignes de certains groupes de lignes, à l'exception de la première ligne du groupe.
SORT itab BY vkont exbel DESCENDING. " Group by VKONT and put highest EXBEL in the group first DELETE ADJACENT DUPLICATES FROM itab COMPARING VKONT.
Il pourrait y avoir des moyens plus efficaces si vous avez besoin de conserver le itab
original intact.
Merci pour votre réponse, mais avec ce code, je reçois juste 1 registre par vkont, au lieu de tous les registres de ce vkont qui ont le même exbel le plus élevé.
À partir de 7.52, vous pouvez sélectionnez sur les tables internes. Exemple de code comme ci-dessous.
TYPES: BEGIN OF ty_s_value, sparte TYPE char2, vkont TYPE char12, exbel TYPE char16, END OF ty_s_value. TYPES: ty_t_value TYPE STANDARD TABLE OF ty_s_value . DATA: lt_value TYPE ty_t_value. lt_value = VALUE #( ( sparte = '05' vkont = '800008422' exbel = '0000000000000001') ( sparte = 'l2' vkont = '800008422' exbel = '0000000000000002') ( sparte = 'l2' vkont = '800008422' exbel = '0000000000000004') ( sparte = '05' vkont = '800008423' exbel = '0000000000000003') ( sparte = 'l2' vkont = '800008423' exbel = '0000000000000002') ( sparte = 'l2' vkont = '800008423' exbel = '0000000000000005') ). SELECT FROM @lt_value AS a FIELDS a~sparte, a~vkont, MAX( a~exbel ) AS exbel GROUP BY a~sparte, a~vkont ORDER BY a~sparte, a~vkont INTO TABLE @DATA(result).
Wow, cette méthode est super simple et intuitive. Malheureusement, je travaille avec la version 740 SAP.
Ce n'est pas seulement 7.52, cela dépend aussi de la base de données et de sa version (OK pour HANA 2.0, mais pas pour Sybase ASE 16.0; il peut être vérifié à l'exécution avec la méthode USE_FEATURES de la classe CL_ABAP_DBFEATURES). Un benchmark de performance serait intéressant à connaître, je crains que SELECT ne soit très lent par rapport aux déclarations ABAP.
@SandraRossi selon l ' aide en ligne la base de données uniquement importe si votre SELECT utilise également la base de données, comme dans un JOIN. Pourquoi et en quoi est-ce important s'il n'est pas utilisé?
@ András Je ne sais pas pourquoi c'est important mais sur mon système 7.52 ASE, le code ci-dessus fait un CX_SY_SQL_UNSUPPORTED_FEATURE "Extension de base de données non prise en charge". Donc, à propos de " Cette instruction ne peut pas être exécutée sur tous les systèmes de base de données, si les données de la table interne doivent être transmises à la base de données ", la question est QUAND doit-elle être transmise?
@SandraRossi Je suppose que lorsque vous faites une jointure en utilisant une table de base de données et une table interne
@ RaúlD.Martín oh.i proposera une solution pour 7.4
@Haojie Comme je l'ai dit, ce n'est pas seulement en cas de jointure, votre code échoue sur mon système 7.52 ASE; mais cela n'échoue plus si je supprime le GROUP BY / ORDER BY. Je pense que les restrictions sont quelque peu liées à celles de Table Buffering , bien que cela dépende également du système de base de données.
@ RaúlD.Martín s'il vous plaît vérifier ma nouvelle réponse pour 740. Merci!
Cela fonctionne avec n'importe quelle version actuellement prise en charge, est plus rapide 2 qu'un TRIER + SUPPRIMER LES DUPLICATS ADJACENTS, et laisse la table d'origine intacte.
FIELD-SYMBOLS: <fs_itab> LIKE LINE OF lt_original. DATA: ls_itab LIKE LINE OF lt_original, lt_hashed TYPE HASHED TABLE OF itab WITH UNIQUE KEY vkont. LOOP AT lt_original INTO ls_itab. READ TABLE lt_hashed ASSIGNING <fs_itab> WITH KEY vkont = ls_itab-vkont. IF sy-subrc = 0. IF ls_itab-exbel > <fs_itab>-exbel. <fs_itab>-exbel = ls_itab-exbel. <fs_itab>-sparte = ls_itab-sparte. "remove this if not needed" ENDIF. ELSE. INSERT ls_itab INTO TABLE lt_hashed. ENDIF. ENDLOOP.
1) SORT + DAD a une échelle de vitesse de O (n * log (n)), alors que celle-ci a O (n)
Remarque pour 1) Pourquoi ne pas utiliser l'instruction COLLECT
car elle utilise également une table hachée (interne)? Ce serait aussi un code plus court, et ce serait probablement plus rapide car c'est fait par le noyau (pas d'interprétation de code d'octet ABAP).
COLLECT ne trouve pas MAX, seulement SUM. Nous obtenons donc les mauvaises valeurs plus rapidement
Voici la solution REDUCE, l'opérateur REDUCE est disponible depuis ABAP 7.40 SP08.
TYPES: BEGIN OF ty_s_value, sparte TYPE char2, vkont TYPE char12, exbel TYPE char16, END OF ty_s_value. TYPES: ty_t_value TYPE STANDARD TABLE OF ty_s_value WITH EMPTY KEY. DATA(lt_tab) = VALUE ty_t_value( ( sparte = '05' vkont = '800000008422' exbel = '1NSN150900000058') ( sparte = 'L2' vkont = '800000008422' exbel = '1NSN150900000058') ( sparte = '05' vkont = '800000008422' exbel = '1NSN150900000037') ( sparte = 'L2' vkont = '800000008422' exbel = '1NSN150900000037') ( sparte = '05' vkont = '800000008422' exbel = '1NSN150900000013') ( sparte = 'L2' vkont = '800000008422' exbel = '1NSN150900000013') ( sparte = '05' vkont = '800000008415' exbel = '1HSN151200000009') ( sparte = 'S1' vkont = '800000008415' exbel = '1HSN151200000009') ( sparte = '05' vkont = '800000008415' exbel = '1HSN151200000008') ( sparte = 'S1' vkont = '800000008415' exbel = '1HSN151200000008') ( sparte = 'L1' vkont = '800000008422' exbel = '1NSN150900000050') ( sparte = 'L1' vkont = '800000008422' exbel = '1NSN150900000029') ... ). DATA(lt_result) = VALUE ty_t_value( FOR GROUPS <group_key> OF <wa> IN lt_tab GROUP BY ( sparte = <wa>-sparte vkont = <wa>-vkont ) LET max2 = REDUCE #( INIT max = VALUE ty_s_value( ) FOR <m> IN GROUP <group_key> NEXT max = COND #( WHEN <m>-exbel > max-exbel THEN <m> ELSE max ) ) IN ( max2 ) ).
BTW, votre jeu de résultats attendu manque la ligne L1, je suppose que dans votre sélection vous respectez non seulement VKONT mais SPARTE aussi.
Veuillez modifier votre question pour clarifier les valeurs que vous attendez. De plus, veuillez joindre le code que vous avez essayé (partie pertinente) et expliquer ce que vous avez obtenu jusqu'à présent. Consultez la page Comment demander .
J'ai édité votre question pour la clarifier, veuillez confirmer si elle correspond à votre question. Si non, veuillez le modifier. Merci.
Merci Sandra. Oui, c'est parfaitement expliqué.