onlyforbopi
6/13/2017 - 8:20 AM

ABAP INTERNAL TABLES

ABAP INTERNAL TABLES

i.e. select ebeln, ebelp, statu, aedat, matnr, menge, meins, netpr, peinh
    up to 10 rows
    from ekpo
    into TABLE @DATA(it_ekko_inline).
Select INTO internal table
*ABAP Code to demonstrate select into internal table command
TYPES: BEGIN OF t_bkpf,
*  include structure bkpf.
  bukrs LIKE bkpf-bukrs,
  belnr LIKE bkpf-belnr,
  gjahr LIKE bkpf-gjahr,
  bldat LIKE bkpf-bldat,
  monat LIKE bkpf-monat,
  budat LIKE bkpf-budat,
  xblnr LIKE bkpf-xblnr,
  awtyp LIKE bkpf-awtyp,
  awkey LIKE bkpf-awkey,
 END OF t_bkpf.
DATA: it_bkpf TYPE STANDARD TABLE OF t_bkpf INITIAL SIZE 0,
      wa_bkpf TYPE t_bkpf.

TYPES: BEGIN OF t_bseg,
*include structure bseg.
  bukrs     LIKE bseg-bukrs,
  belnr     LIKE bseg-belnr,
  gjahr     LIKE bseg-gjahr,
  buzei     LIKE bseg-buzei,
  mwskz     LIKE bseg-mwskz,         "Tax code
  umsks     LIKE bseg-umsks,         "Special G/L transaction type
  prctr     LIKE bseg-prctr,         "Profit Centre
  hkont     LIKE bseg-hkont,         "G/L account
  xauto     LIKE bseg-xauto,
  koart     LIKE bseg-koart,
  dmbtr     LIKE bseg-dmbtr,
  mwart     LIKE bseg-mwart,
  hwbas     LIKE bseg-hwbas,
  aufnr     LIKE bseg-aufnr,
  projk     LIKE bseg-projk,
  shkzg     LIKE bseg-shkzg,
  kokrs     LIKE bseg-kokrs,
 END OF t_bseg.
DATA: it_bseg TYPE STANDARD TABLE OF t_bseg INITIAL SIZE 0,
      wa_bseg TYPE t_bseg.

DATA: it_ekko TYPE STANDARD TABLE OF ekko.


*Select all fields of a SAP database table into in itab
SELECT *
  FROM ekko
  INTO TABLE it_ekko.

*Inline Version - (difference is you don't need the data declaration above)
select *
    from ekpo
    into TABLE @DATA(it_ekko2).
  "see here for more info and examples of the inline @DATA & DATA syntax


*Select directly into an internal table
SELECT bukrs belnr gjahr buzei mwskz umsks prctr hkont xauto koart
       dmbtr mwart hwbas aufnr projk shkzg kokrs
  FROM bseg
  INTO TABLE it_bseg.


* Select directly into an internal table where fields are in a
* different order or not all fields are specified 
SELECT bukrs belnr gjahr buzei mwskz umsks prctr hkont xauto koart
       dmbtr mwart hwbas aufnr projk shkzg kokrs
  FROM bseg
  INTO CORRESPONDING FIELDS OF TABLE it_bseg.
Select... endselect statement
The SELECT..ENDSELECT statement acts like a loop command and any coding within it will be performed on each loop pass. This syntax should generally be avoided unless it only retrieves a small number of records and is only performed once i.e. it is not within a nested loop.
*Select... endselect command
SELECT bukrs belnr gjahr buzei mwskz umsks prctr hkont xauto koart
       dmbtr mwart hwbas aufnr projk shkzg kokrs
  FROM bseg
  INTO wa_bseg.

  APPEND wa_bseg TO it_bseg.
ENDSELECT.
Select FOR ALL ENTRIES statement
The FOR ALL ENTRIES statement addition restricts the result to only those that exist within the passed internal table. However if the for all entries table is initial(empty), then all records will be retrieved.
*Select FOR ALL ENTRIES command
SELECT bukrs belnr gjahr bldat monat budat xblnr awtyp awkey
  UP TO 100 ROWS
  FROM bkpf
  INTO TABLE it_bkpf.

IF sy-subrc EQ 0.
* The FOR ALL ENTRIES command only retrieves data which matches
* entries within a particular internal table.
  SELECT bukrs belnr gjahr buzei mwskz umsks prctr hkont xauto koart
         dmbtr mwart hwbas aufnr projk shkzg kokrs
    FROM bseg
    INTO TABLE it_bseg
    FOR ALL ENTRIES IN it_bkpf
    WHERE bukrs EQ it_bkpf-bukrs AND
          belnr EQ it_bkpf-belnr AND
          gjahr EQ it_bkpf-gjahr.
ENDIF.
Select SINGLE statement
The SELECT SINGLE addition only selects one record. Originally this required you to include the full key within the where clause, and to retrieve 1 row without the full key you had to use the "UP TO" addition. This is no longer the case and you can use SELECT SINGLE without the full table key.
*Select Single with full table key retrieves ONLY one row if available
SELECT * "all fields
    FROM bseg
    INTO TABLE it_bseg
    WHERE bukrs EQ wa_bseg-bukrs AND
          belnr EQ wa_bseg-belnr AND
          gjahr EQ wa_bseg-gjahr AND
          buzei EQ wa_bseg-BUZEI

*Select Single without full table key. Syntactically correct and still retrieves ONLY one row if available
SELECT * "all fields
    FROM bseg
    INTO TABLE it_bseg
    WHERE bukrs EQ wa_bseg-bukrs AND
          belnr EQ wa_bseg-belnr.

Select UP TO .. Rows
The select UP TO n ROWS addition selects up to a specific number of rows. "UP TO 1 ROWS" will select 1 row if 1 exists and "UP TO 1000 ROWS" will select up to 1000 rows if they exist based on the selection criteria. 

Please note that even if you have the UP TO 1000 ROWS addition it will still only select based on the where clause, so it may still only select 10, 200, 300, 500 etc if that's all it returns but not more than 1000.
*Select UP TO 1 ROWS - Retrieves ONLY one row if available
SELECT * "select all fields
    FROM bseg
    UP TO 1 ROWS
    INTO TABLE it_bseg
    WHERE bukrs EQ wa_bseg-bukrs AND
          belnr EQ wa_bseg-belnr.

*Select UP TO 1000 ROWS - Retrieves no more than 1000 rows
SELECT * "select all fields
    FROM bseg
    UP TO 1000 ROWS
    INTO TABLE it_bseg
    WHERE bukrs EQ wa_bseg-bukrs AND
          belnr EQ wa_bseg-belnr.
*ABAP Code to demonstrate select into internal table command

* TYPE DECLARATION
* USING TYPE + DECLARE METHOD
TYPES: BEGIN OF t_bkpf,
*  include structure bkpf.
  bukrs LIKE bkpf-bukrs,
  belnr LIKE bkpf-belnr,
  gjahr LIKE bkpf-gjahr,
  bldat LIKE bkpf-bldat,
  monat LIKE bkpf-monat,
  budat LIKE bkpf-budat,
  xblnr LIKE bkpf-xblnr,
  awtyp LIKE bkpf-awtyp,
  awkey LIKE bkpf-awkey,
 END OF t_bkpf.
* TABLE AND WORK AREA DECLARATION
DATA: it_bkpf TYPE STANDARD TABLE OF t_bkpf INITIAL SIZE 0,
      wa_bkpf TYPE t_bkpf.

* TYPE DECLARATION
TYPES: BEGIN OF t_bseg,
*include structure bseg.
  bukrs     LIKE bseg-bukrs,
  belnr     LIKE bseg-belnr,
  gjahr     LIKE bseg-gjahr,
  buzei     LIKE bseg-buzei,
  mwskz     LIKE bseg-mwskz,         "Tax code
  umsks     LIKE bseg-umsks,         "Special G/L transaction type
  prctr     LIKE bseg-prctr,         "Profit Centre
  hkont     LIKE bseg-hkont,         "G/L account
  xauto     LIKE bseg-xauto,
  koart     LIKE bseg-koart,
  dmbtr     LIKE bseg-dmbtr,
  mwart     LIKE bseg-mwart,
  hwbas     LIKE bseg-hwbas,
  aufnr     LIKE bseg-aufnr,
  projk     LIKE bseg-projk,
  shkzg     LIKE bseg-shkzg,
  kokrs     LIKE bseg-kokrs,
 END OF t_bseg.

*TABLE AND WORK AREA DECLARATION 
DATA: it_bseg TYPE STANDARD TABLE OF t_bseg INITIAL SIZE 0,
      wa_bseg TYPE t_bseg.

*TABLE DECLARATION 
DATA: it_ekko TYPE STANDARD TABLE OF ekko

*************************************************************************
* 1ST WAY
* Select all fields of a SAP database table into in itab
SELECT *
  FROM ekko
  INTO TABLE it_ekko.
  

*************************************************************************
* 2ND WAY
* Select directly into an internal table
* Here we select specific fields.
SELECT bukrs belnr gjahr buzei mwskz umsks prctr hkont xauto koart
       dmbtr mwart hwbas aufnr projk shkzg kokrs
  FROM bseg
  INTO TABLE it_bseg.

*************************************************************************
* 3RD WAY  
* Select directly into an internal table where fields are in a
* different order or not all fields are specified
* HERE WE HAVE TO USE "INTO CORRESPONDING FIELDS OF TABLE" 
* that can also be used in the previous scenarios.
SELECT bukrs belnr gjahr buzei mwskz umsks prctr hkont xauto koart
       dmbtr mwart hwbas aufnr projk shkzg kokrs
  FROM bseg
  INTO CORRESPONDING FIELDS OF TABLE it_bseg.


*******************************************************************************
* 4TH WAY
*The SELECT..ENDSELECT statement acts like a loop command and any coding within 
*it will be performed on each loop pass. This syntax should generally be 
*avoided unless it only retrieves a small number of records and is only 
*performed once i.e. it is not within a nested loop.

*Select... endselect command
SELECT bukrs belnr gjahr buzei mwskz umsks prctr hkont xauto koart
       dmbtr mwart hwbas aufnr projk shkzg kokrs
  FROM bseg
  INTO wa_bseg.

  APPEND wa_bseg TO it_bseg.
ENDSELECT.



*******************************************************************************
* 5TH WAY
* Select FOR ALL ENTRIES statement
*The FOR ALL ENTRIES statement addition restricts the result to only those that 
*exist within the passed internal table. However if the for all entries table 
*is initial(empty), then all records will be retrieved.

*Select FOR ALL ENTRIES command
SELECT bukrs belnr gjahr bldat monat budat xblnr awtyp awkey
  UP TO 100 ROWS
  FROM bkpf
  INTO TABLE it_bkpf.

IF sy-subrc EQ 0.
* The FOR ALL ENTRIES command only retrieves data which matches
* entries within a particular internal table.
  SELECT bukrs belnr gjahr buzei mwskz umsks prctr hkont xauto koart
         dmbtr mwart hwbas aufnr projk shkzg kokrs
    FROM bseg
    INTO TABLE it_bseg
    FOR ALL ENTRIES IN it_bkpf
    WHERE bukrs EQ it_bkpf-bukrs AND
          belnr EQ it_bkpf-belnr AND
          gjahr EQ it_bkpf-gjahr.
ENDIF.


* EX 
*Select FOR ALL ENTRIES command
data: it_ekko type STANDARD TABLE OF ekko,
      wa_ekko like line of it_ekko,
      it_ekpo type standard table of ekpo,
      wa_ekpo like line of it_ekpo.

SELECT *
  UP TO 10 ROWS  "only return first 10 hits
  FROM ekko
  INTO TABLE it_ekko.
loop at it_ekko into wa_ekko.
  write:/ wa_ekko-ebeln.
endloop.

IF sy-subrc EQ 0.
* The FOR ALL ENTRIES comand only retrieves data which matches
* entries within a particular internal table.
  SELECT *
    FROM ekpo
    INTO TABLE it_ekpo
    FOR ALL ENTRIES IN it_ekko
    WHERE ebeln EQ it_ekko-ebeln.
  write:/ 'FOR ALL ENTRIES comand '.
  loop at it_ekpo into wa_ekpo.
    write:/ wa_ekpo-ebeln, wa_ekpo-ebelp.
  endloop.
ENDIF.

* If we use FOR ALL ENTRIES addition but use an itab
* that is empty then the command will return nothing.

* SELECT FOR ALL ENTRIES is the best alternative for SELECT WITH JOINS
* FOR READING DATA FROM MORE THAN 2 TABLES.

* A classic scenario is when we need to join a text file 
* with a db table, we load the text file into itab
* then use for all entries like this: 

* When we use into corresponding fields, the fields of tha
* target table need to have the same name as the fields of the
* origin table.

SELECT *
      FROM dfkkop
      INTO CORRESPONDING FIELDS OF TABLE gt_dfkkop
      FOR ALL ENTRIES IN gt_dfkkop_file
      WHERE vkont = gt_dfkkop_file-vkont
      "%_hints db6 '<IXSCAN TABLE=''DFKKOP'' INDEX=''"DFKKOP~ZDT"'' />'
                "* AND spras eq sy-langu.





********************************************************************************
* 6TH WAY - Select SINGLE statement
* The SELECT SINGLE addition only selects one record. Originally this required you
* to include the full key within the where clause, and to retrieve 1 row without 
* the full key you had to use the "UP TO" addition. This is no longer the case 
* and you can use SELECT SINGLE without the full table key.

*Select Single with full table key retrieves ONLY one row if available
SELECT SINGLE * "all fields
    FROM bseg
    INTO TABLE it_bseg
    WHERE bukrs EQ wa_bseg-bukrs AND
          belnr EQ wa_bseg-belnr AND
          gjahr EQ wa_bseg-gjahr AND
          buzei EQ wa_bseg-BUZEI

*Select Single without full table key. Syntactically correct and still retrieves 
*ONLY one row if available
SELECT SINGLE * "all fields
    FROM bseg
    INTO TABLE it_bseg
    WHERE bukrs EQ wa_bseg-bukrs AND
          belnr EQ wa_bseg-belnr.
          

* Ex 1 - Select Single
DATA : WA_MARA TYPE MARA. " Declare work area

SELECT SINGLE * 
  FROM MARA 
  INTO WA_MARA 
  WHERE MATNR = '0001'. " Read exact record from MARA table

WRITE : wa_mara-matnr, wa_mara-mtart, wa_mara-meins. " Print data to screen





********************************************************************************
* 6TH WAY - Select UP TO n ROWS          
*The select UP TO n ROWS addition selects up to a specific number of rows. 
*UP TO 1 ROWS" will select 1 row if 1 exists and "UP TO 1000 ROWS" will select 
*up to 1000 rows if they exist based on the selection criteria. 
*Please note that even if you have the UP TO 1000 ROWS addition it will still 
*only select based on the where clause, so it may still only select 10, 200, 
*300, 500 etc if thats all it returns but not more than 1000.

*Select UP TO 1 ROWS - Retrieves ONLY one row if available
SELECT * "select all fields
    FROM bseg
    UP TO 1 ROWS
    INTO TABLE it_bseg
    WHERE bukrs EQ wa_bseg-bukrs AND
          belnr EQ wa_bseg-belnr.

*Select UP TO 1000 ROWS - Retrieves no more than 1000 rows
SELECT * "select all fields
    FROM bseg
    UP TO 1000 ROWS
    INTO TABLE it_bseg
    WHERE bukrs EQ wa_bseg-bukrs AND
          belnr EQ wa_bseg-belnr.
    
    
* Example : SELECT UP TO
DATA : IT_MARA TYPE TABLE OF MARA. " Declare internal table
DATA : WA_MARA TYPE MARA. " Declare work area

SELECT * 
  FROM MARA 
  INTO WA_MARA 
  UP TO 50 ROWS 
  WHERE MTART = 'FERT'. " Read 50 appropriate records from MARA table here MTART is not a keyfield
ENDSELECT.

LOOP AT IT_MARA INTO WA_MARA.
write :/ wa_mara-matnr, wa_mara-mtart, wa_mara-meins. " Print data to screen
ENDLOOP.
      

********************************************************************************
* SELECT - INTO CORRESPONDING SUBTYPES
* This block will detail all the different ways we can use SELECT and INTO
* CORRESPONDING FIELDS like ex.2 in previous section.

* DECLARATION OF TYPES FOR THE CREATION OF ITAB
TYPES: BEGIN OF ty_dd03l_required_columns,
tabname   LIKE dd03l–tabname,
fieldname LIKE dd03l–fieldname,
reftable  LIKE dd03l–reftable,
       END OF ty_dd03l_required_columns.
* DECLARATION OF TABLE USING THE PREVIOUS TYPE.
DATA: t_dd03l_req TYPE STANDARD TABLE OF ty_dd03l_required_columns.

* DECLARATION OF ITAB based on db table or other itab
* Often times though, the target structure is simply defined based on the table definition.
DATA: t_dd03l_full TYPE STANDARD TABLE OF dd03l.

* DECLARATION OF A SIMPLE CONSTANT.
CONSTANTS: c_tabname LIKE dd03l–tabname VALUE ‘BUS_DI’.

 
* Now let us compare six different ways to code the ABAP SQL statement for the 
*selection.

* EX

TYPES : BEGIN OF TY_MARA,
 "USER DEFINED TYPE WITH FOUR FIELDS
        MATNR TYPE MARA-MATNR,
        MTART TYPE MARA-MTART,
        MBRSH TYPE MARA-MBRSH,
        MEINS TYPE MARA-MEINS,
        END OF TY_MARA.
DATA : IT_MARA TYPE TABLE OF TY_MARA . "INTERNAL TABLE FOR USER DEFINED TYPE
DATA : WA_MARA TYPE TY_MARA . "WORK AREA FOR USER DEFINED TYPE
SELECT * FROM MARA
       INTO CORRESPONDING FIELDS OF TABLE IT_MARA
       UP TO 50 ROWS.
LOOP AT IT_MARA INTO WA_MARA.
WRITE :/ WA_MARA-MATNR, WA_MARA-MTART, WA_MARA-MBRSH, WA_MARA-MEINS.  "DISPLAY OUTPUT
ENDLOOP.
 
********************************************************************************
* ex 1 - WITH LISTING OF THE REQUIRED COLUMNS.
* (1) The standard and of course correct way is to list the required columns.
SELECT tabname
fieldname
reftable
       INTO TABLE t_dd03l_req
       FROM dd03l
       WHERE tabname = c_tabname.

 
********************************************************************************
* ex 2 - USING WILDCARDS + INTO CORRESPONDING.
* (2) Another way to do it is using “*” in conjunction with INTO CORRESPONDING. 
* This is where the “urban legend” has it that this would affect performance.

SELECT * INTO CORRESPONDING FIELDS OF TABLE t_dd03l_req
       FROM dd03l
       WHERE tabname = c_tabname.

 
********************************************************************************
* ex 3 - WITH FIELD LIST + INTO CORRESPONDING
* (3) Just for comparison, let us also include this combination of field list 
* and INTO CORRESPONDING.

SELECT tabname
fieldname
reftable
       INTO CORRESPONDING FIELDS OF TABLE t_dd03l_req
       FROM dd03l
       WHERE tabname = c_tabname.

 
********************************************************************************
* ex 4 - FULL TARGET STRUCTURE + INTO CORRESPONDING
* (4) Now switching to the full target structure, a combination of field list 
* and INTO CORRESPONDING will likely not affect the run time, however more 
* memory will be occupied this way.


SELECT tabname
fieldname
reftable
       INTO CORRESPONDING FIELDS OF TABLE t_dd03l_full
       FROM dd03l
       WHERE tabname = c_tabname.

 
********************************************************************************
* ex 5 - WILDCARDS + INTO CORRESONDING
* (5) The combination of “*”, INTO CORRESPONDING and the full target structure 
* must be avoided. This looks very similar to number 2 and probably helped 
* leading to the bad image of this construct.

SELECT * INTO CORRESPONDING FIELDS OF TABLE t_dd03l_full
       FROM dd03l
       WHERE tabname = c_tabname.

 
********************************************************************************
* EX 6 - Using all columns of the table.
(6) Of course there might be cases where you really need (almost) all of the columns of a table.

SELECT * INTO TABLE t_dd03l_full
       FROM dd03l
       WHERE tabname = c_tabname.



********************************************************************************
* SELECT + JOIN TABLES
* This section will display how we can join db tables and then perform the
* query on them:

Syntax :

 SELECT T1~FIELD1
        T1~FIELD2
        T2~FIELD1
        T2~FIELD2
        INTO TABLE <ITAB>
        
 FROM T1 INNER JOIN T2 ON ( T1~FIELD1 = T2~FIELD )
 WHERE T1~FIELD = <SOME VALUE> .

** Here T1 and T2 are database tables, FIELD1 and FIELD2 are fields in the respective tables


* ex 1 
**DATA DECLERATIONS
TYPES: BEGIN OF T_MARA,
  MATNR LIKE MARA-MATNR,  "FIELD1 FROM MARA TABLE
  MTART TYPE MARA-MTART,  "FIELD2 FROM MARA TABLE
  MAKTX TYPE MAKT-MAKTX,  "FIELD1 FROM MAKT TABLE
  SPRAS TYPE MAKT-SPRAS,  "FIELD2 FROM MAKT TABLE
END OF T_MARA.

DATA: IT_MARA TYPE  TABLE OF T_MARA .
DATA : WA_MARA TYPE T_MARA.
SELECT MARA~MATNR
       MARA~MTART
       MAKT~MAKTX
       MAKT~SPRAS
  INTO  TABLE IT_MARA
  FROM MARA INNER JOIN MAKT ON ( MARA~MATNR = MAKT~MATNR )
  UP TO 50 ROWS.


LOOP AT IT_MARA INTO WA_MARA.
  WRITE : / WA_MARA-MATNR, WA_MARA-MTART, WA_MARA-MAKTX, WA_MARA-SPRAS .
ENDLOOP.

* Ex 2
Start of query, here we use * to select all fields
  SELECT *
*    vktyp vkona
*    APPENDING CORRESPONDING FIELDS OF TABLE zdfkkop
*    PACKAGE SIZE 50000

       " As p : Alias for dfkkop
       " From <table> as <alias> = which table we get data from
     FROM dfkkop AS p

       " Here we inner join tables ffkkvk(alias k) on field k~vkont and connect it to table dfkkop(alias p) on field vkont
     INNER JOIN fkkvk AS k ON k~vkont = p~vkont

       " We assign all values before the where clause to the table we originally declared gt_dfkkop
     INTO CORRESPONDING FIELDS OF TABLE gt_dfkkop " STATEMENT A

       " Here we start our where clause
     WHERE  p~AUGST = p_AUGST

       " We want the value of AUGST in alias p to be assigned the value of p_AUGST (parameter)\
       " When we use parameters we use the equality to assign

       " Here we set second condition and we join it with AND
       " When we assign select options we use IN for the left value to be in the range
        AND p~stakz IN s_stakz
        AND p~blart IN s_blart
        AND p~augrs IN s_augrs
        AND p~augdt IN s_augdt
        AND p~vkont IN s_vkont
        AND k~vktyp IN s_vktyp.


********************************************************************************
* SELECT + JOINS + DB INDEXING

**************************************************************************
* SELECT DICTINCT
* Gets distinct values of a column from a db table
SELECT DISTINCT  
  FROM  
  INTO TABLE  
  WHERE .


* Ex.

  TYPES: BEGIN OF ty_mtart,
           mtart TYPE mara-mtart,
         END OF ty_mtart.
  DATA: it_mtart TYPE TABLE OF ty_mtart,
        wa_mtart TYPE          ty_mtart.
START-OF-SELECTION.
  SELECT DISTINCT mtart FROM mara INTO TABLE it_mtart UP TO 5 ROWS.

  LOOP AT it_mtart INTO wa_mtart.
    WRITE:/ wa_mtart-mtart.
  ENDLOOP.
  
*******************************************
* SELECT WITH BYPASSING BUFFER

* Whenever we fetch data in SAP, it will get data
* from the buffer rea for better performance, some tables though
* may update very fast, so in some scenarios the buffer needs to get
* bypassed to get the real time data.

select * FROM  INTO TABLE  BYPASSING BUFFER.

Example for SELECT WITH BYPASSING BUFFER in SAP ABAP 

The below example is used to fetch data from MARA(Material Master) table bypassing buffer. 


TYPES: BEGIN OF ty_mara,
         matnr TYPE mara-matnr,
         mtart TYPE mara-mtart,
       END OF ty_mara.
DATA: it_mara TYPE TABLE OF ty_mara,
      wa_mara TYPE          ty_mara.

START-OF-SELECTION.
  SELECT matnr mtart FROM mara INTO TABLE it_mara BYPASSING BUFFER.

  LOOP AT it_mara INTO wa_mara.
    WRITE:/ wa_mara-matnr, wa_mara-mtart.
  ENDLOOP.
  SELECT *
    INTO CORRESPONDING FIELDS OF TABLE gt_rf_out
    FROM fkkvkp as vkp
    INNER JOIN fkkvk as vk ON
      vkp~vkont = vk~vkont
	IINER JOIN ever as e ON
	   e~vkonto = vkp~vkont
    WHERE vkp~vkont IN s_vkont
	AND e~loebm = ''.

ENDFORM.                    "get_data

1. Declaration of Internal Tables        - itabdeclare.abap
2. Population of Internal Tables         - itabpopulate.abap
3. Copying of Interlan Tables            - itabcopy.abap
4. Loop over Internal Tables             - itabloop.abap
5. Print Internal Tables on Screen       - itabprint.abap
6. Delete Internal Tables                - itabdelete.abap
7. Count lines of Internal Tables        - itabcountlines.abap
8. Modify Internal Tables                - itabmodify.abap
9. Select from Internal Tables           - itabselect.abap
10. Select from itab with OPEN CURSOR    - itabopencursor.abap
11. Select + Into Internal table         - Selectvarious.abap
12. Select with Double inner join        - Selectdouble.abap
13. Many select examples for all cases   - all_select.abap
Select INTO internal table
*ABAP Code to demonstrate select into internal table command
TYPES: BEGIN OF t_bkpf,
*  include structure bkpf.
  bukrs LIKE bkpf-bukrs,
  belnr LIKE bkpf-belnr,
  gjahr LIKE bkpf-gjahr,
  bldat LIKE bkpf-bldat,
  monat LIKE bkpf-monat,
  budat LIKE bkpf-budat,
  xblnr LIKE bkpf-xblnr,
  awtyp LIKE bkpf-awtyp,
  awkey LIKE bkpf-awkey,
 END OF t_bkpf.
DATA: it_bkpf TYPE STANDARD TABLE OF t_bkpf INITIAL SIZE 0,
      wa_bkpf TYPE t_bkpf.

TYPES: BEGIN OF t_bseg,
*include structure bseg.
  bukrs     LIKE bseg-bukrs,
  belnr     LIKE bseg-belnr,
  gjahr     LIKE bseg-gjahr,
  buzei     LIKE bseg-buzei,
  mwskz     LIKE bseg-mwskz,         "Tax code
  umsks     LIKE bseg-umsks,         "Special G/L transaction type
  prctr     LIKE bseg-prctr,         "Profit Centre
  hkont     LIKE bseg-hkont,         "G/L account
  xauto     LIKE bseg-xauto,
  koart     LIKE bseg-koart,
  dmbtr     LIKE bseg-dmbtr,
  mwart     LIKE bseg-mwart,
  hwbas     LIKE bseg-hwbas,
  aufnr     LIKE bseg-aufnr,
  projk     LIKE bseg-projk,
  shkzg     LIKE bseg-shkzg,
  kokrs     LIKE bseg-kokrs,
 END OF t_bseg.
DATA: it_bseg TYPE STANDARD TABLE OF t_bseg INITIAL SIZE 0,
      wa_bseg TYPE t_bseg.

DATA: it_ekko TYPE STANDARD TABLE OF ekko.


*Select all fields of a SAP database table into in itab
SELECT *
  FROM ekko
  INTO TABLE it_ekko.

*Inline Version - (difference is you don't need the data declaration above)
select *
    from ekpo
    into TABLE @DATA(it_ekko2).
  "see here for more info and examples of the inline @DATA & DATA syntax


*Select directly into an internal table
SELECT bukrs belnr gjahr buzei mwskz umsks prctr hkont xauto koart
       dmbtr mwart hwbas aufnr projk shkzg kokrs
  FROM bseg
  INTO TABLE it_bseg.


* Select directly into an internal table where fields are in a
* different order or not all fields are specified 
SELECT bukrs belnr gjahr buzei mwskz umsks prctr hkont xauto koart
       dmbtr mwart hwbas aufnr projk shkzg kokrs
  FROM bseg
  INTO CORRESPONDING FIELDS OF TABLE it_bseg.
  

*Select... endselect statement
*The SELECT..ENDSELECT statement acts like a loop command and any coding within it will be performed on each loop pass. This syntax should generally be avoided unless it only retrieves a small number of records and is only performed once i.e. it is not within a nested loop.
*Select... endselect command
SELECT bukrs belnr gjahr buzei mwskz umsks prctr hkont xauto koart
       dmbtr mwart hwbas aufnr projk shkzg kokrs
  FROM bseg
  INTO wa_bseg.

  APPEND wa_bseg TO it_bseg.
ENDSELECT.
Select FOR ALL ENTRIES statement
The FOR ALL ENTRIES statement addition restricts the result to only those that exist within the passed internal table. However if the for all entries table is initial(empty), then all records will be retrieved.
*Select FOR ALL ENTRIES command
SELECT bukrs belnr gjahr bldat monat budat xblnr awtyp awkey
  UP TO 100 ROWS
  FROM bkpf
  INTO TABLE it_bkpf.

IF sy-subrc EQ 0.
* The FOR ALL ENTRIES command only retrieves data which matches
* entries within a particular internal table.
  SELECT bukrs belnr gjahr buzei mwskz umsks prctr hkont xauto koart
         dmbtr mwart hwbas aufnr projk shkzg kokrs
    FROM bseg
    INTO TABLE it_bseg
    FOR ALL ENTRIES IN it_bkpf
    WHERE bukrs EQ it_bkpf-bukrs AND
          belnr EQ it_bkpf-belnr AND
          gjahr EQ it_bkpf-gjahr.
ENDIF.
Select SINGLE statement
The SELECT SINGLE addition only selects one record. Originally this required you to include the full key within the where clause, and to retrieve 1 row without the full key you had to use the "UP TO" addition. This is no longer the case and you can use SELECT SINGLE without the full table key.
*Select Single with full table key retrieves ONLY one row if available
SELECT * "all fields
    FROM bseg
    INTO TABLE it_bseg
    WHERE bukrs EQ wa_bseg-bukrs AND
          belnr EQ wa_bseg-belnr AND
          gjahr EQ wa_bseg-gjahr AND
          buzei EQ wa_bseg-BUZEI

*Select Single without full table key. Syntactically correct and still retrieves ONLY one row if available
SELECT * "all fields
    FROM bseg
    INTO TABLE it_bseg
    WHERE bukrs EQ wa_bseg-bukrs AND
          belnr EQ wa_bseg-belnr.

*Select UP TO .. Rows
The select UP TO n ROWS addition selects up to a specific number of rows. "UP TO 1 ROWS" will select 1 row if 1 exists and "UP TO 1000 ROWS" will select up to 1000 rows if they exist based on the selection criteria. 

*Please note that even if you have the UP TO 1000 ROWS addition it will still only select based on the where clause, so it may still only select 10, 200, 300, 500 etc if that's all it returns but not more than 1000.
*Select UP TO 1 ROWS - Retrieves ONLY one row if available
SELECT * "select all fields
    FROM bseg
    UP TO 1 ROWS
    INTO TABLE it_bseg
    WHERE bukrs EQ wa_bseg-bukrs AND
          belnr EQ wa_bseg-belnr.

*Select UP TO 1000 ROWS - Retrieves no more than 1000 rows
SELECT * "select all fields
    FROM bseg
    UP TO 1000 ROWS
    INTO TABLE it_bseg
    WHERE bukrs EQ wa_bseg-bukrs AND
          belnr EQ wa_bseg-belnr.
" Print entire table
DATA: BEGIN OF T OCCURS 100,
        BAREA(5), BLNCE(5),
      END OF T.

LOOP AT T.
  WRITE: / T-BAREA, T-BLNCE.
ENDLOOP.

" Print second line of table
DATA: BEGIN OF T OCCURS 100,
        BAREA(5), BLNCE(5),
      END OF T.

LOOP AT T.
  IF sy-tabix = 2.
    WRITE: / T-BAREA, T-BLNCE.
  ENDIF.
ENDLOOP.

" Print from line to line (ie from 7 to 8)
DATA: BEGIN OF T OCCURS 100,
        BAREA(5), BLNCE(5),
      END OF T.

LOOP AT T FROM 7 TO 8.
  WRITE: / T-BAREA, T-BLNCE.
ENDLOOP.

" Print only lines that satisfy condition (using Where)
DATA: BEGIN OF T OCCURS 100,
        BAREA(5), BLNCE(5),
      END OF T.

LOOP AT T WHERE BAREA > 0.
  WRITE: / T-BAREA, T-BLNCE.
ENDLOOP.

"which has the same effect as: (using Check)

LOOP AT T.
  CHECK T-BAREA > 0.
  WRITE: / T-BAREA, T-BLNCE.
ENDLOOP.
*&---------------------------------------------------------------------*
*& Report  ZTEE_PD_CSR_TEST_2
*&
*&---------------------------------------------------------------------*
*&
*&   Function:
*&   Enter package or programmer name, output list with
*&   all codes written by said programmer, or belonging
*&   to that package.
*&
*&   Using DB tables: TADIR.
*&
*&   Techniques:
*&        OPEN CURSOR
*&        SELECTION-SCREEN PROGRAMMING
*&        BASIC ALV REPORTS
*&
*&
*&
*&
*&
*&---------------------------------------------------------------------*

REPORT  ZTEE_PD_CSR_TEST_2.

type-pools:slis.
TABLES: tadir.

DATA: go_alv  TYPE REF TO cl_salv_table.


DATA gs_tadir LIKE tadir.
DATA gst_tadir TYPE tadir.
DATA t_tadir LIKE TABLE OF gs_tadir.
DATA t_wa_tadir LIKE LINE OF t_tadir.
"DATA gst_tadir LIKE LINE OF gs_tadir.
DATA crs_tadir TYPE cursor.

SELECTION-SCREEN SKIP.
SELECTION-SCREEN BEGIN OF BLOCK BACKGROUND WITH FRAME TITLE A2BG.
SELECTION-SCREEN BEGIN OF BLOCK SELECTION WITH FRAME TITLE A1TITLE.

SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT (32) A1LINE1 FOR FIELD p_author.
"PARAMETERS:
SELECT-OPTIONS: p_author FOR tadir-author.
SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT (29) A1LINE2 FOR FIELD p_dev.
SELECT-OPTIONS: p_dev FOR tadir-devclass.
SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT (29) B11LINE1 FOR FIELD p_but1.
PARAMETERS: p_but1 RADIOBUTTON GROUP RAD1.
SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT (30) B11LINE2 FOR FIELD p_but2.
PARAMETERS: p_but2  RADIOBUTTON GROUP RAD1.
SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT (30) B11LINE3 FOR FIELD p_but3.
PARAMETERS: p_but3  RADIOBUTTON GROUP RAD1.
SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN: END OF BLOCK SELECTION.
SELECTION-SCREEN SKIP.
SELECTION-SCREEN SKIP.
SELECTION-SCREEN SKIP.
SELECTION-SCREEN END OF BLOCK BACKGROUND.

INITIALIZATION.
  PERFORM SELECTION_SCREEN_TEXT.



START-OF-SELECTION.
  PERFORM get_data.
  PERFORM out_data.



*&---------------------------------------------------------------------*
*&      Form  GET_DATA
*&
*&  Input: None - The parameter/selection fields are not required
*&               to have a value.
*&  Output: Writes to screen and File.
*&  Usage: PERFORM get_data
*&
*& Job: Performs the query
*&      Fills internal table with query results
*&      Creates output filename and opens it
*&      Sorts internal table containing query results
*&      Loops over lines of internal table, writes on screen
*&
*&
*&
*&---------------------------------------------------------------------*
FORM get_data.

***************************************
* Basic Select with multiple fields
* Filling internal table gt_ever with contents of ever
* Notes : p_bstat, s_kofix, s_vrefer are the variables
* corresponding to the screen selection parameters.


  OPEN CURSOR crs_tadir
  FOR SELECT  *
*          e~vkonto
*         e~kofiz
*          e~bstatus
*          e~vrefer
    FROM  tadir as e
    WHERE     e~author IN p_author
    AND       e~devclass IN p_dev.

  DO.
    FETCH NEXT CURSOR crs_tadir
    "FETCH NEXT CURSOR crs_tadir INTO gst_tadir.
    INTO CORRESPONDING FIELDS OF gs_tadir.


    "INSERT gs_tadir INTO t_tadir.
    APPEND gs_tadir TO t_tadir.
    IF sy-subrc <> 0.
      CLOSE CURSOR crs_tadir.
      EXIT.
    ENDIF.


  ENDDO.

ENDFORM.                    "get_data


*&---------------------------------------------------------------------*
*&      Form  out_data
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM out_data.
*  LOOP AT t_tadir INTO gst_tadir.
*    WRITE: /
*          gst_tadir-obj_name,
*          gst_tadir-devclass.
*  ENDLOOP.

  if p_but1 = 'X'.
    try.
      CALL METHOD cl_salv_table=>factory
      IMPORTING
        r_salv_table = go_alv
      CHANGING
        t_table = t_tadir.

    go_alv->display( ).
    endtry.


*    CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY' "CALL FUNCTION MODULE TO DISPLAY ALV GRID
*    EXPORTING
*      I_CALLBACK_PROGRAM = SY-REPID "SY-REPID IS A SYSTEM VARIABLE WHICH STORES CURRENT PROGRAM NAME
*      I_STRUCTURE_NAME = 'TADIR'
*      TABLES
*      T_OUTTAB = t_tadir. "PASS INTERNAL TABLE TO DISPLAY ALV FORMAT





  ELSEIF p_but2 = 'X'.
    LOOP AT t_tadir INTO gst_tadir.
    WRITE: /
          gst_tadir-obj_name,
          gst_tadir-devclass.
    ENDLOOP.
  ELSEIF p_but3 = 'X'.
    CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY' "CALL FUNCTION MODULE TO DISPLAY ALV GRID
    EXPORTING
      I_CALLBACK_PROGRAM = SY-REPID "SY-REPID IS A SYSTEM VARIABLE WHICH STORES CURRENT PROGRAM NAME
      I_STRUCTURE_NAME = 'TADIR'
      TABLES
      T_OUTTAB = t_tadir. "PASS INTERNAL TABLE TO DISPLAY ALV FORMAT
  ENDIF.


ENDFORM.                    "out_data


*&---------------------------------------------------------------------*
*&      Form  selection_screen_text
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM SELECTION_SCREEN_TEXT.
  A1TITLE = 'Code Finder'.
  A1LINE1 = 'Name of Programmer:'.
  A1LINE2 = 'Name of Package:'.
  A2BG = 'AOAOAOA'.
  B11LINE1 = 'parameter'.
  B11LINE2 = 'parameter2'.
ENDFORM.                    " selection_screen_text


********************************************************************************
********************************************************************************
********************************************************************************
********************************************************************************
* Ways to use OPEN CURSOR/FETCH (THIS IS NOT PART OF THE PROGRAM ABOVE)

OPEN CURSOR / FETCH can be used instead of SELECT for quicker retrieval of data from large tables.

In general, these are the ways we can populate a table using SELECT or OPEN CURSOR:

Syntax:

OPEN CURSOR [WITH HOLD] dbcur FOR
	SELECT RESULT
	FROM SOURCE
	[[FOR ALL ENTRIES IN itab] WHERE sql_cond ]
	[GROUP BY group][HAVING group_cond]
	[ORDER BY sort_key ]. 

This statement opens a database cursor for the selection defined after FOR, and associates
a cursor variable dbcur with this database cursor. The result set of the selection can be
read with the statement FETCH.

Cursor dbcur expects a declared variable with the specific predefined data type cursor.
A database cursor dbcur that has already been opened cannot be opened again. A line of the 
result set is always assigned to an opened database cursor as a cursor position. After the
OPEN CURSOR statement, the database cursor is positioned in front of the first line of the
result set.

After FOR, the syntax of a SELECT statement can be entered which contains all the additions 
of the normal SELECT statement, except for INTO and APPENDING. In the addition result, the
addition SINGLE also cannot be used after SELECT.

Only a limited number of database cursors can be open at the same time. An open database cursor
can be closed using the statement CLOSE CURSOR. In addition, an open database cursor is closed
for a database commit or a database rollback.

If a cursor variable dbcur of an open database cursor is assigned to another cursor variable
or passed as a parameter, the latter is associated with the same database cursor at the same
position. A cursor variable of an open database cursor can also be passed to procedures that
have been called externally, to enable the database cursor to be accessed from there.

In the normal SELECT statement, the data from the selection is always read directly into the
target area specified by the INTO clause during the select statement. When we use a cursor to read data, 
we decouple the process from the SELECT statement. To do this, we must open a cursor for the 
SELECT statement. 

Example:  
Opening and Closing Cursors:
	OPEN CURSOR [WITH HOLD] <c> 
		FOR SELECT <result>
		FROM <source>
		[WHERE <condition>]
		[GROUP BY <fields>]
		[HAVING <condition>]
		[ORDER BY <fields>]

We must first have declared the cursor

"1. Single cursor into work area (SELECT/ENDSELECT)
SELECT (gt_fields)
      FROM (g_table)
        INTO gs_wa
        BYPASSING BUFFER
        WHERE (gt_where1).
      ADD 1 TO g_count.
ENDSELECT.

"2. Single cursor into table (Work area is not used)	
SELECT (gt_fields)
      FROM (g_table)
      INTO TABLE gt_1 
	  BYPASSING BUFFER
        WHERE (gt_where1).
		
"3. Multi cursor, single process into work area
" OPEN CURSOR / FETCH constructs into a work area. 
" Extra code is required to avoid an endless LOOP and 
" do cursor maintenance.

OPEN CURSOR l_c1 FOR
	SELECT (gt_fields)
	FROM (g_table)
	BYPASSING BUFFER
	WHERE (gt_where1)

	WHILE NOT L_c1 IS INITIAL.
	
	IF NOT l_c1 IS INITIAL.
		FETCH NEXT CURSOR l_c1 INTO gs_wa.
		
		IF sy-subrc EQ 0.
			ADD 1 TO g_count.
		ELSE.
			CLOSE CURSOS l_c1.
		ENDIF.
	ENDIF.
	
	ENDWHILE.
	

"4. Multi cursor, single process into table
" OPEN CURSOR / FETCH constructs into a table. 
" Code overhead is required to avoid ENDLESS LOOP
" and do cursor maintenance.
OPEN CURSOR l_c1 FOR
      SELECT (gt_fields)
      FROM (g_table)
       BYPASSING BUFFER
        WHERE (gt_where1).
  
   WHILE NOT l_c1 IS INITIAL.
  
    IF NOT l_c1 IS INITIAL.
      FETCH NEXT CURSOR l_c1 INTO TABLE gt_1 PACKAGE SIZE p_pkg.
      IF sy-subrc EQ 0.
        DESCRIBE TABLE gt_1 LINES g_lines.
        ADD g_lines TO g_count.
      ELSE.
        CLOSE CURSOR l_c1.
      ENDIF.
    ENDIF.
  
   ENDWHILE.
   

"5. Multi cursor, multi process into work area
"Identical with mode 3, OPEN CURSOR/FETCH constructs into work area,
"however each SELECT statement is called within its own RFC's starting
"in a new task, on a particular server group.
CALL FUNCTION 'ZGSFETCH' STARTING NEW TASK 'ZGSC1'
      DESTINATION IN GROUP p_svrgp
      PERFORMING return_info ON END OF TASK
        EXPORTING
            i_mode      = 'W'
            i_pkg       = p_pkg
            i_tablename = g_table
            it_fields   = gt_fields
            it_where    = gt_where1
       EXCEPTIONS
         OTHERS                = 1.
		 
" Using the function module:
OPEN CURSOR l_cursor FOR
  SELECT (it_fields)
    FROM (i_tablename)
     BYPASSING BUFFER
      WHERE (it_where).
  
  
    WHILE NOT l_cursor IS INITIAL.
      FETCH NEXT CURSOR l_cursor INTO CORRESPONDING FIELDS OF ls_wa.
  
      IF sy-subrc EQ 0.
        ADD 1 TO e_lines.
      ELSE.
        CLOSE CURSOR l_cursor.
      ENDIF.
  
    ENDWHILE.
	
"5. Multi cursor, multi process into table.
"Identical as Mode 4, OPEN CURSOR/FETCH constructs into a table, 
"however each SELECT statement is called within its own RFC's starting in a 
"new task, on a particular server group.
" Using ZGSTEST Construct.
    CALL FUNCTION 'ZGSFETCH'
      STARTING NEW TASK 'ZGSC1'
      DESTINATION IN GROUP p_svrgp
      PERFORMING return_info ON END OF TASK
        EXPORTING
            i_mode      = 'T'
            i_pkg       = p_pkg
            i_tablename = g_table
            it_fields   = gt_fields
            it_where    = gt_where1
        EXCEPTIONS
             OTHERS    = 1.
			 

" Call the function module
 OPEN CURSOR l_cursor FOR
  SELECT (it_fields)
    FROM (i_tablename)
     BYPASSING BUFFER
      WHERE (it_where).
  
    WHILE NOT l_cursor IS INITIAL.
  
*simply overwrite the table
      FETCH NEXT CURSOR l_cursor
      INTO CORRESPONDING FIELDS OF TABLE lt_1 PACKAGE SIZE i_pkg.
  
      DESCRIBE TABLE lt_1 LINES l_lines.
  
      IF sy-subrc EQ 0.
        ADD l_lines TO e_lines.
      ELSE.
        CLOSE CURSOR l_cursor.
      ENDIF.
  
    ENDWHILE.			 
 
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
********************************************************************************
"Using LOOP....ENDLOOP. in SAP ABAP
"Loop...Endloop. is also used to read data from a internal table into work area, 
"this is used to read multiple records serially one after one .

"Syntax1: LOOP AT <ITAB> INTO <WA> .
"         ENDLOOP.

"Syntax2: LOOP AT <ITAB> INTO <WA> WHERE <FIELDS1> = <VALUE> .
"         ENDLOOP.

"Syntax3: LOOP AT <ITAB> INTO <WA> FROM <INDEX1> TO "<INDEX2>.
"         ENDLOOP.

"""""
********************************************************************************
"Basic form
LOOP AT itab. 

"Basic form with work area
LOOP AT itab INTO wa.

"Additions
    "1. ... FROM n1 
    "2. ... TO n2 
    "3. ... WHERE logexp 
    "4. ... TRANSPORTING NO FIELDS 

"Effect
"Processes an internal table (DATA ) in a loop which begins with LOOP and ends 
"with ENDLOOP . Each of the internal table entries is sent to the output area in turn. 

"When LOOP AT itab. is used, the header line of the internal table itab is used 
"as output area. In the case of LOOP AT itab INTO wa , there is an explicitly 
"specified work area wa . 

"If the internal table is empty, all the statements between LOOP and ENDLOOP are 
"ignored. 

"In each loop pass, SY-TABIX contains the index of the current table entry. 
"After leaving a LOOP , SY-TABIX has the same value as it had before. 

"Inserting and/or deleting lines in a LOOP affects subsequent loop passes. 

"For control break processing in a LOOP on internal tables, there are special 
"control break control structures for internal tables you can use. 

"You can use the CONTINUE statement to leave the current loop pass prematurely 
"and continue with the next loop pass. To leave loop processing altogether, you use EXIT . 

"At the end of loop processing (i.e. after ENDLOOP ), the return code value of SY-SUBRC 
"specifies whether the loop was actually processed. 

    "SY-SUBRC = 0 The loop was executed at least once. 
    "SY_SUBRC = 4 The loop was not executed, either because there was no entry at
    "              all or because there was no entry which satisfied the conditions. 

********************************************************************************
"Example

"The table T is defined as follows: 
DATA: BEGIN OF T OCCURS 100,
        BAREA(2), BLNCE TYPE P,
      END OF T.

"After the table has been filled with data (using APPEND ), it is then output: 
LOOP AT T.
  WRITE: / T-BAREA, T-BLNCE.
ENDLOOP.

"Notes
"If an internal table is processed only on a restricted basis (with the additions 
"FROM , TO and /or WHERE ), you should not use the control structures for control
"break processing because the interaction of a restricted LOOP and the AT statement
"is undefined at present. 

"If SUM is used in a LOOP and an explicit output area wa has also been specified, 
"this output area must be compatible with the line type of the internal table itab . 

"Addition 1

"... FROM n1

"Addition 2

"... TO n2 

"Effect
"Places all internal table entries from the entry with the index ( SY-TABIX ) = n1
"to the entry with the index = n2 inclusive in the output area in turn. 

"Notes
"If either one of the additions " FROM n1 " or " TO n2 " is missing, then the 
"table is processed either from the first entry or up to the last entry 
"(according to what is missing). 

"Example
"Output table entries 7 and 8: 

DATA: BEGIN OF T OCCURS 100,
        BAREA(5), BLNCE(5),
      END OF T.

LOOP AT T FROM 7 TO 8.
  WRITE: / T-BAREA, T-BLNCE.
ENDLOOP.

"Addition 3
"... WHERE logexp 

"Effect
"Places all internal table entries which satisfy the condition logexp in turn in the output area. The condition logexp can be almost any logical expression . The only restriction is that the first field for each comparison must be a sub-field of the line structure of the internal table itab . 

"Example
DATA: BEGIN OF T OCCURS 100,
        BAREA(5), BLNCE(5),
      END OF T.

LOOP AT T WHERE BAREA > 0.
  WRITE: / T-BAREA, T-BLNCE.
ENDLOOP.

"which has the same effect as: 

LOOP AT T.
  CHECK T-BAREA > 0.
  WRITE: / T-BAREA, T-BLNCE.
ENDLOOP.

"Notes
"The interaction between the LOOP AT ... WHERE statement and the AT control 
"break statements is currently undefined. It is therefore important to avoid 
"using either the AT NEW/END OF or FIRST/LAST statements in a LOOP loop with a 
"WHERE condition. The performance of a LOOP AT ... WHERE statement can be improved 
"significantly if the fields to be compared always have the same data type. The comparison fields should be defined as follows: 

"DATA LIKE . 

"Example

DATA: BEGIN OF T OCCURS 100,
        BAREA(5), BLNCE(5),
      END OF T.
DATA CMP_BAREA LIKE T-BAREA.
CMP_BAREA = '01'.

LOOP AT T WHERE BAREA = CMP_BAREA.
  WRITE: / T-BAREA, T-BLNCE.
ENDLOOP.

"Addition 4
"... TRANSPORTING NO FIELDS 

"Effect
"There is no field transport in the output area of the internal table. This 
"addition can be used only in conjunction with a WHERE condition. Since it would
"make no sense to specify a work area with INTO wa when using the addition 
"TRANSPORTING NO FIELDS , this option does not exist. 

"This addition can be used to determine a set of line indexes (index set) or 
"to determine the number of lines in a table which satisfy a given condition. 

"Example
"Determining the number COUNT of lines in a name table TAB which contain the 
"name 'Walter' and the corresponding index set INDEX_SET . 

DATA: BEGIN OF TAB OCCURS 100,
        NAME(30) TYPE C,
      END OF TAB,
      COUNT TYPE I,
      INDEX_SET LIKE SY-TABIX OCCURS 10 WITH HEADER LINE.

LOOP AT TAB TRANSPORTING NO FIELDS WHERE NAME CS 'Walter'.
  INDEX_SET = SY-TABIX.
  APPEND INDEX_SET.
  ADD 1 TO COUNT.
ENDLOOP.

""""""
" SIMPLE USES

"For displaying the data which is in the internal table.
Loop at IT_KNA1. 
 WRITE :/IT_KNA1-CUST_NO, IT_KNA1-NAME, IT_KNA1-CNTRY. 
ENDLOOP.

"Similarly as mentioned above for entering data, for displaying also. The first 
"record from the body of the internal table is fetched into the work-area and 
"then output is displayed, and procedure repeats for all the records in the internal table.

"Notes:
"How to Loop from second row in internal table?

"You can use if condition in the loop endloop. (using sy-tabix)
LOOP AT it_tab1  .

  IF sy-tabix > 1. 
    WRITE: / it_tab1-mandt,it_tab1-matnr . 
   ENDIF.

ENDLOOP.

"Notes:
"How to Loop from second row to 100th row in internal table (using sy-tabix)

"You can use if condition in the loop endloop.
LOOP AT it_tab1  .

  IF sy-tabix > 1 AND sy-tabix < 100. 
    WRITE: / it_tab1-mandt,it_tab1-matnr . 
   ENDIF.

ENDLOOP.




"""
***************************************************************
* Table declaration (old method)
DATA: BEGIN OF tab_ekpo OCCURS 0,             "itab with header line
  ebeln TYPE ekpo-ebeln,
  ebelp TYPE ekpo-ebelp,
 END OF tab_ekpo.

DATA: ls_tab_ekpo LIKE LINE OF tab_ekpo.

* Ex:
DATA: BEGIN OF gt_ever OCCURS 0,
        vkonto    LIKE  ever-vkonto,
        kofiz     LIKE  ever-kofiz,
        bstatus   LIKE  ever-bstatus,
        vrefer    LIKE  ever-vrefer,
      END OF gt_ever.

***************************************************************
*Table declaration (new method - 1)     "USE THIS WAY!!!
TYPES: BEGIN OF t_ekpo,
  ebeln TYPE ekpo-ebeln,
  ebelp TYPE ekpo-ebelp,
 END OF t_ekpo.
DATA: it_ekpo TYPE STANDARD TABLE OF t_ekpo INITIAL SIZE 0,      "itab
      wa_ekpo TYPE t_ekpo.                    "work area (header line)
      
*Ex.
TYPES: BEGIN OF ty_vbak,
  vbeln TYPE vbak-vbeln,
  auart TYPE vbak-auart,
  vkorg TYPE vbak-vkorg,
  END OF ty_vbak
DATA: t_vbak TYPE STANDARD TABLE OF ty_vbak WITH HEADER LINE.
DATA: ls_vbak LIKE LINE OF t_vbak             "work area (header line)


*****************************************************************************

* Declaration of Internal Table with structure like database table
DATA: <itabname> LIKE <dbtable> OCCURS 0 [WITH HEADER LINE]
DATA: <workareaname> LIKE LINE OF <itabname>

DATA: gs_ever LIKE ever OCCURS 0 WITH HEADER LINE.
DATA: ls_gs_ever LIKE LINE OF gs_ever.

*****************************************************************************
* Build internal table and work area from existing internal table
DATA: <itabname> LIKE <itabname2> OCCURS 0 [WITH HEADER LINE],
      <wa_itabname> LIKE LINE OF <itabname>


DATA: it_datatab LIKE tab_ekpo OCCURS 0,      "old method
      wa_datatab LIKE LINE OF tab_ekpo.       " work area declaration

      
*****************************************************************************
* Build internal table and work area from existing internal table,
* adding additional fields

TYPES: BEGIN OF <structuretype>.
       INCLUDE STRUCTURE <itab or dbtable>.
TYPES: <fieldname> TYPE <dbtable-fieldname>,
       <fieldname2> TYPE <dbtable-fieldname>.
TYPES: END OF <structuretype>

DATA: <itabname> TYPE STANDARD TABLE OF <structuretype> INITIAL SIZE 0,
      <wa_itab>  TYPE <structuretype>.



TYPES: BEGIN OF t_repdata.
        INCLUDE STRUCTURE tab_ekpo.  "could include EKKO table itself!!
TYPES: bukrs  TYPE ekpo-werks,
       bstyp  TYPE ekpo-bukrs.
TYPES: END OF t_repdata.
DATA: it_repdata TYPE STANDARD TABLE OF t_repdata INITIAL SIZE 0,   "itab
      wa_repdata TYPE t_repdata. 
      

****************************************************************************
* DEFINE / DECLARE INTERNAL TABLE
****************************************************************************
*Two major ways to declare itabs:
	
*REFERENCE TO GLOBAL TABLE OR STRUCTURED DATA LINE.
*( ΣΤΟΝ ΠΡΩΤΟ ΤΡΟΠΟ ΔΗΛΩΣΗΣ ITAB ΧΡΗΣΙΜΟΠΟΙΟΥΜΕ REFERENCE ΣΕ ΕΝΑ
* ΠΙΝΑΚΑ Η ENA STRUCTURED LINE TYPE ΠΟΥ ΥΠΑΡΧΕΙ ΗΔΗ)
	
		  "Globally (In the Abap Dictionary - se11)
			"Table structure is first created in abap dictionary. 
			"Then a table is defined in the program, of the type of structure we have declared.
			(bc_400_T = table type / db table)
			
			ie.
			(Declare Table Type in se11 - BC400_T)
			" in code
			DATA gt_flights TYPE bc400_T
			
			"The above table will have a line structure bc400_s_flights
			
		  "Locally  (Declared within a program)
			"Table structure is declared locally within the program
			"Internal table is declared loccaly as well, with reference to the structure.
			(bc400_s_flight = structure)
			
			"ie 
			TYPES: 	gty_t_flights TYPE STANDARD TABLE OF BC400_s_flight
						WITH NON-UNIQUE KEY carrid connid fldate.
						
						* Here BC400_s_flight is a Line structure
		
		"ΑΝΕΞΑΡΤΗΤΗ ΔΗΛΩΣΗ ITAB
		"( ΕΔΩ ΔΗΛΩΝΟΥΜΕ ΕΝΑ ΕΣΩΤΕΡΙΚΟ ΠΙΝΑΚΑ ΧΩΡΙΣ ΚΑΠΟΙΑ ΑΝΑΦΟΡΑ ΣΕ ΠΙΝΑΚΑ ΤΗΣ
		"ΒΑΣΗΣ Η ΣΕ ΚΑΠΙΟ STRUCTURED LINE TYPE, ΑΝΤΙ ΑΥΤΟΥ ΤΑ ΔΗΛΩΝΟΥΜΕ ΕΜΕΙΣ)
		
		"IE.
		" Declaring Local structure type
		TYPES: BEGIN OF gty_s_type,
				carrid TYPE s_carr_id,
				connid TYPE s_conn_id,
				....,
				END OF gty_s_type
				
		" Declaring internal table with the Local structure type
		DATA: gt_itab TYPE STANDARD TABLE OF gty_s_type WITH UNIQUE KEY
		" Other varieties of table declaration using "TABLE OF"
		"DATA: gt_itab TYPE STANDARD TABLE OF gty_s_type WITH NON-UNIQUE KEY
		"DATA: gt_itab TYPE SORTED TABLE OF gty_s_type WITH UNIQUE KEY
		"DATA: gt_itab TYPE SORTED TABLE OF gty_s_type WITH NON-UNIQUE KEY
		"DATA: gt_itab TYPE HASHED TABLE OF gty_s_type WITH UNIQUE KEY
		"DATA: gt_itab TYPE HASHED TABLE OF gty_s_type WITH NON-UNIQUE KEY
		
		" Declaring internal table with Header line
		DATA: gt_itab TYPE STANDARD TABLE OF gty_s_type WITH HEADER LINE.
		" Other varieties of table declaration using "TABLE OF"
		"DATA: gt_itab TYPE STANDARD TABLE OF gty_s_type WITH HEADER LINE.
		"DATA: gt_itab TYPE SORTED TABLE OF gty_s_type WITH HEADER LINE.
		"DATA: gt_itab TYPE SORTED TABLE OF gty_s_type WITH HEADER LINE.
		"DATA: gt_itab TYPE HASHED TABLE OF gty_s_type WITH HEADER LINE.
		"DATA: gt_itab TYPE HASHED TABLE OF gty_s_type WITH HEADER LINE.
		
		" Declaring internal table with Header line + Declaring Line structure of Header line
		DATA: gt_itab TYPE HASHED TABLE OF gty_s_type WITH HEADER LINE.
		DATA: gs_ls_itab LIKE LINE OF gt_itab.
		
*###########################
*SYNOPSIS : WAYS TO DECLARE INTERNAL TABLES
		*
		DATA <itabname> TYPE <TableType or DB table or constructed from Abap Dictionary)
		*
		DATA <itabname> TYPE [STANDARD|SORTED|HASHED] TABLE OF [Structured Line type] [WITH HEADER LINE] [WITH UNIQUE KEY|WITH NON-UNIQUE KEY]
		*
		DATA <itabname> TYPE TABLE OF [Structured Line Type]
		*
		DATA <itabname> TYPE [STANDARD|SORTED|HASHED] TABLE OF [Structured Line type] [WITH HEADER LINE] [WITH UNIQUE KEY|WITH NON-UNIQUE KEY]
		DATA: <structured line name> LIKE LINE OF <itabname>
		*
		DATA: <itabname> TYPE [STANDARD|SORTED|HASHED] TABLE OF [Structured Line type] [WITH HEADER LINE] [WITH UNIQUE KEY|WITH NON-UNIQUE KEY]
		DATA: <structured line name> TYPE <Structured line type>
		*
		DATA: <itabname> LIKE <table type or itab> OCCURS 0 [WITH HEADER LINE]
		DATA: <structured line name> LIKE LINE of <Table type>
		*
		DATA <itabname> TYPE <itab or db table> OCCURS 0 WITH HEADER LINE.
		DATA: <structured line name> LIKE LINE of <Table type>
		
		DATA: BEGIN OF <itabname> OCCURS 0,
			vbeln LIKE vbak-vbeln,
			auart LIKE vbak-auart,
			vkorg LIKE vbak-vkorg,
			END OF gt_vbak.

		DATA: ls_gt_vbak LIKE LINE of gt_vbak.		
		*
		
		
*&---------------------------------------------------------------------*
*& Report  ZTEE_PD_EVER_COPYITAB
*&
*&---------------------------------------------------------------------*
*&
*& WAYS TO COPY INTERNAL TABLES:
*&
*&
*&
*&    1. Using LOOP to copy itab to another itab
*& 
*&     TYPES:
*&       BEGIN OF ty_vbak,
*&         vbeln TYPE vbak-vbeln,
*&         auart TYPE vbak-auart,
*&         vkorg TYPE vbak-vkorg,
*&       END   OF ty_vbak.
*&
*&     DATA: t_vbak  TYPE STANDARD TABLE OF ty_vbak.
*&     DATA: ls_vbak LIKE LINE OF t_vbak.
*&     DATA: t_vbeln TYPE STANDARD TABLE OF vbak-vbeln.
*&     DATA: lv_lines TYPE i.
*& 
*&     * Some test data
*&     SELECT vbeln auart vkorg
*&       FROM vbak
*&       INTO TABLE t_vbak
*&       UP TO 500 ROWS.
*& 
*&     CLEAR t_vbeln.
*&     LOOP AT t_vbak INTO ls_vbak.
*&       APPEND ls_vbak-vbeln TO t_vbeln.
*&     ENDLOOP.
*& 
*&     * Display number of entries in target table
*&     lv_lines = LINES( t_vbeln ).
*&     WRITE lv_lines.
*&
*&------------------------------------------------------------------------*
*&
*&    2. Using MOVE to copy
*& 
*&    CLEAR t_vbeln.
*&    MOVE t_vbak TO t_vbeln.
*& 
*&    * Display number of entries in target table
*&    lv_lines = LINES( t_vbeln ).
*&    WRITE lv_lines.
*&
*&-------------------------------------------------------------------------*
*&
*&  3. Using APPEND LINES OF to copy
*&
*&  CLEAR t_vbeln.
*&  APPEND LINES OF t_vbak TO t_vbeln.
*& 
*&  * Display number of entries in target table
*&  lv_lines = LINES( t_vbeln ).
*&  WRITE lv_lines.
*&
*&--------------------------------------------------------------------------*
*&
*&  4. Using direct copy
*& 
*&  CLEAR t_vbeln.
*&  t_vbeln = t_vbak.
*& 
*&  * Display number of entries in target table
*&  lv_lines = LINES( t_vbeln ).
*&  WRITE lv_lines.
*&
*&--------------------------------------------------------------------------*
*& FUNCTION FORM.
*&
*& FUNCTION z_move_corresponding_table.
*&*"----------------------------------------------------------------------
*&*"*"Local Interface:
*&*"  IMPORTING
*&*"     REFERENCE(IT_TABLE) TYPE  TABLE
*&*"  EXPORTING
*&*"     REFERENCE(ET_TABLE) TYPE  TABLE
*&*"----------------------------------------------------------------------
*& 
*&    DATA: er_line TYPE REF TO DATA.
*& 
*&    FIELD-SYMBOLS:  TYPE ANY,
*&                    TYPE ANY.
*& 
*&    CLEAR et_table.
*& 
*&    CREATE DATA er_line LIKE LINE OF et_table.
*&    ASSIGN er_line-&gt;* TO .
*& 
*&    LOOP AT it_table ASSIGNING .
*&      MOVE-CORRESPONDING  TO .
*&      APPEND  TO et_table.
*&    ENDLOOP.
*& 
*&  ENDFUNCTION.
*&
*&---------------------------------------------------------------------*

REPORT  ZTEE_PD_EVER_COPYITAB.

* Declare database table
TABLES: vbak.

* Declare line structure
TYPES:
  BEGIN OF ty_vbak,
    vbeln TYPE vbak-vbeln,
    auart TYPE vbak-auart,
    vkorg TYPE vbak-vkorg,
  END OF ty_vbak.


* Declare itab using the line structure we declared (with Header Line) 
* Declare variable like line-type of t_vbak.
"DATA: t_vbak TYPE STANDARD TABLE OF ty_vbak WITH HEADER LINE.
DATA: t_vbak TYPE STANDARD TABLE OF ty_vbak WITH HEADER LINE.
DATA: ls_vbak LIKE LINE OF t_vbak.

* Declare itab with one field, of the type vbak-vbeln. (without Header Line)
* Declare variable structure line the line-type of t_vbeln.
DATA: t_vbeln TYPE STANDARD TABLE OF vbak-vbeln.
DATA: ls_t_vbeln LIKE LINE OF t_vbeln.

* Declare itab with one field, of the type vbak-vbeln. (without Header Line)
* Declare variable structure line the line-type of t_vbeln2.
DATA: t_vbeln2 TYPE STANDARD TABLE OF vbak-vbeln.
DATA: ls_t_vbeln2 LIKE LINE OF t_vbeln2.

* Declare itab with one field, of the type vbak-vbeln. (with Header Line)
* Declare variable structure line the line-type of t_vbeln3.
DATA: t_vbeln3 TYPE STANDARD TABLE OF ty_vbak WITH HEADER LINE.
DATA: ls_t_vbeln3 LIKE LINE OF t_vbeln2.

* Declare itab with one field, of the type vbak-vbeln. (with Header Line)
* Declare variable structure line the line-type of t_vbeln3.
DATA: t_vbeln4 TYPE STANDARD TABLE OF ty_vbak WITH HEADER LINE.
DATA: ls_t_vbeln4 LIKE LINE OF t_vbeln2.

* Declare itab with one field, of the type vbak-vbeln. (with Header Line)
* Declare variable structure line the line-type of t_vbeln5.
DATA: t_vbeln5 TYPE STANDARD TABLE OF vbak-vbeln.
DATA: ls_t_vbeln5 LIKE LINE OF t_vbeln2.

* Declare integer variable
DATA: lv_lines TYPE i.

* Declare itab using the LIKE statement
* Declare line structure of itab
DATA: gs_vbak LIKE t_vbak OCCURS 0 WITH HEADER LINE.
DATA: ls_gs_vbak LIKE LINE of gs_vbak.

* Declare itab using BEGIN statement, with declared structure
* Declare line structure of gt_vbak.
DATA: BEGIN OF gt_vbak OCCURS 0,
  vbeln LIKE vbak-vbeln,
  auart LIKE vbak-auart,
  vkorg LIKE vbak-vkorg,
  END OF gt_vbak.

DATA: ls_gt_vbak LIKE LINE of gt_vbak.


************************************************************************
* Selection Screen.
SELECT-OPTIONS:

             s_vbeln FOR vbak-vbeln,
             s_auart FOR vbak-auart,
             s_vkorg FOR vbak-vkorg.
             
************************************************************************             
START-OF-SELECTION.
             
             
     PERFORM get_data.
             
             
FORM get_data.
  
        SELECT vbeln auart vkorg
          FROM vbak as e
          INTO CORRESPONDING FIELDS OF TABLE t_vbak
          UP TO 500 ROWS
          WHERE e~vbeln IN s_vbeln.
          "UP TO 500 ROWS.
          
          
       CLEAR t_vbeln.
       CLEAR t_vbeln2.
       CLEAR t_vbeln3.
       CLEAR t_vbeln4.
       CLEAR gs_vbak.
       CLEAR gt_vbak.
       
       
       " FIRST WAY TO COPY : USE LOOP + APPEND
       LOOP AT t_vbak INTO ls_vbak.
         APPEND ls_vbak-vbeln TO t_vbeln.
         APPEND ls_vbak-vbeln TO gs_vbak.
         APPEND ls_vbak TO gt_vbak.
       ENDLOOP.

       " SECOND WAY : USE MOVE
       " BOTH TABLES NEED TO EITHER HAVE HEADER LIEN, OR NOT
       MOVE t_vbeln TO t_vbeln2.
       
       " THIRD WAY: USE APPEND LINES OF
       " BOTH TABLES NEED TO EITHER HAVE HEADER LINE, OR NTO
       " BETTER FOR CASES OF ITABS WITH HEADER LINE
       APPEND LINES OF t_vbak TO t_vbeln3.
       
       " FOURTH WAY: STANDARD COPY
       t_vbeln4[] = t_vbak[].
       t_vbeln5 = t_vbeln.

* Measure table lines         
lv_lines = LINES( t_vbeln ).
WRITE lv_lines.
lv_lines = LINES( t_vbeln2 ).
WRITE lv_lines.
lv_lines = LINES( t_vbeln3 ).
WRITE lv_lines.
lv_lines = LINES( t_vbeln4 ).
WRITE lv_lines.
lv_lines = LINES( t_vbeln5 ).
WRITE lv_lines.
lv_lines = LINES( gs_vbak ).
WRITE lv_lines. 
lv_lines = LINES( gt_vbak ).
WRITE lv_lines.   



* Works because we have declared header line
LOOP AT t_vbak.
  WRITE: / "'1',
    t_vbak-vbeln,
    t_vbak-auart.
ENDLOOP.


* Will not work, we have not declared header line
*LOOP AT t_vbeln.
*  WRITE: / "'1',
*    t_vbeln,
*    "t_vbak-auart.
*ENDLOOP.

* Works
* LOOP AT gs_vbak.
*  WRITE: / "'1',
*    gs_vbak-vbeln.
*ENDLOOP.

* Works
*LOOP AT gt_vbak.
*  WRITE: / "'1',
*    gt_vbak-vbeln,
*    gt_vbak-auart.
*ENDLOOP.


ENDFORM.  
* Itab declare (for output)
* Using DATA:BEGIN OF OCCURS
* When using BEGIN OF - OCCURS header line is auto created.
* - gt_ebill_out - custom structure, 4 fields from ebill, 4 from fkkvkp
DATA: BEGIN OF gt_ebill_out OCCURS 0,
          vkont LIKE zbi_ebill_ca-vkont,
          email_notify LIKE zbi_ebill_ca-email_notify,
          sms_notify LIKE zbi_ebill_ca-sms_notify,
          paper_notify LIKE zbi_ebill_ca-paper_notify,
          monthly LIKE zbi_ebill_ca-monthly,
          email_fis LIKE fkkvkp-email_fis,
          smsin_fis LIKE fkkvkp-smsin_fis,
          pbill_fis LIKE fkkvkp-pbill_fis,
          fkmonthly LIKE fkkvkp-monthly,
          END OF gt_ebill_out.

DATA: wa_gt_ebill LIKE LINE OF gt_ebill_out.


FORM get_data.



*  2019-05-07 add.
  SELECT ca~vkont ca~email_notify ca~sms_notify ca~paper_notify ca~monthly fk~email_fis fk~smsin_fis fk~pbill_fis fk~monthly
    FROM zbi_ebill_ca AS ca
    INNER JOIN fkkvkp AS fk ON
            ca~vkont = fk~vkont
   into (wa_gt_ebill-vkont, wa_gt_ebill-email_notify, wa_gt_ebill-sms_notify, wa_gt_ebill-paper_notify, wa_gt_ebill-monthly, wa_gt_ebill-email_fis, wa_gt_ebill-smsin_fis, wa_gt_ebill-pbill_fis, wa_gt_ebill-fkmonthly).
*  2019-05-07 comment next line.
*    wa_gt_ebill-FKMONTHLY = wa_gt_ebill-MONTHLY.
    APPEND wa_gt_ebill TO gt_ebill_out.
  ENDSELECT.
  
ENDFORM.
* Itab declare (for output)
* Using DATA:BEGIN OF OCCURS
* When using BEGIN OF - OCCURS header line is auto created.
* - gt_ebill_out - custom structure, 4 fields from ebill, 4 from fkkvkp
DATA: BEGIN OF gt_ebill_out OCCURS 0,
          vkont LIKE zbi_ebill_ca-vkont,
          email_notify LIKE zbi_ebill_ca-email_notify,
          sms_notify LIKE zbi_ebill_ca-sms_notify,
          paper_notify LIKE zbi_ebill_ca-paper_notify,
          monthly LIKE zbi_ebill_ca-monthly,
          email_fis LIKE fkkvkp-email_fis,
          smsin_fis LIKE fkkvkp-smsin_fis,
          pbill_fis LIKE fkkvkp-pbill_fis,
          fkmonthly LIKE fkkvkp-monthly,
          END OF gt_ebill_out.

DATA: wa_gt_ebill LIKE LINE OF gt_ebill_out.




FORM get_data.



*  2019-05-07 add.
  SELECT ca~vkont ca~email_notify ca~sms_notify ca~paper_notify ca~monthly fk~email_fis fk~smsin_fis fk~pbill_fis fk~monthly
    FROM zbi_ebill_ca AS ca
    INNER JOIN fkkvkp AS fk ON
            ca~vkont = fk~vkont
   into (wa_gt_ebill-vkont, wa_gt_ebill-email_notify, wa_gt_ebill-sms_notify, wa_gt_ebill-paper_notify, wa_gt_ebill-monthly, wa_gt_ebill-email_fis, wa_gt_ebill-smsin_fis, wa_gt_ebill-pbill_fis, wa_gt_ebill-fkmonthly).
*  2019-05-07 comment next line.
*    wa_gt_ebill-FKMONTHLY = wa_gt_ebill-MONTHLY.
    APPEND wa_gt_ebill TO gt_ebill_out.
  ENDSELECT.



  LOOP AT gt_ebill_out INTO wa_gt_ebill.


    IF     ( wa_gt_ebill-email_notify = wa_gt_ebill-email_fis )
      AND  ( wa_gt_ebill-sms_notify = wa_gt_ebill-smsin_fis )
      AND  ( wa_gt_ebill-paper_notify = wa_gt_ebill-pbill_fis )
      AND  ( wa_gt_ebill-monthly = wa_gt_ebill-fkmonthly ).
      DELETE gt_ebill_out.
    ELSE.
      ADD 1 TO mismatch.
    ENDIF.

  ENDLOOP.


ENDFORM.      
* Syntax: SELECT * FROM <DATABASE TABLE>
*        INTO CORRESPONDING FIELDS OF TABLE <INTERNAL TABLE> .
        
        
REPORT ZSAPN_SELECT_CORRESPONDING.
TYPES : BEGIN OF TY_MARA,
 "USER DEFINED TYPE WITH FOUR FIELDS
        MATNR TYPE MARA-MATNR,
        MTART TYPE MARA-MTART,
        MBRSH TYPE MARA-MBRSH,
        MEINS TYPE MARA-MEINS,
        END OF TY_MARA.
DATA : IT_MARA TYPE TABLE OF TY_MARA . "INTERNAL TABLE FOR USER DEFINED TYPE
DATA : WA_MARA TYPE TY_MARA . "WORK AREA FOR USER DEFINED TYPE
SELECT * FROM MARA
       INTO CORRESPONDING FIELDS OF TABLE IT_MARA
       UP TO 50 ROWS.
LOOP AT IT_MARA INTO WA_MARA.
WRITE :/ WA_MARA-MATNR, WA_MARA-MTART, WA_MARA-MBRSH, WA_MARA-MEINS.  "DISPLAY OUTPUT
ENDLOOP.



TYPES: BEGIN OF ty_dd03l_required_columns,
tabname   LIKE dd03l–tabname,
fieldname LIKE dd03l–fieldname,
reftable  LIKE dd03l–reftable,

       END OF ty_dd03l_required_columns.
DATA: t_dd03l_req TYPE STANDARD TABLE OF ty_dd03l_required_columns.

 

Often times though, the target structure is simply defined based 
on the table definition.

 

DATA: t_dd03l_full TYPE STANDARD TABLE OF dd03l.

CONSTANTS: c_tabname LIKE dd03l–tabname VALUE ‘BUS_DI’.

 

Now let us compare six different ways to code the ABAP SQL statement 
for the selection.

 

(1) The standard and of course correct way is to list the required columns.

 

SELECT tabname
fieldname
reftable
       INTO TABLE t_dd03l_req
       FROM dd03l
       WHERE tabname = c_tabname.

 

(2) Another way to do it is using “*” in conjunction with INTO CORRESPONDING. 
This is where the “urban legend” has it that this would affect performance.

 

SELECT * INTO CORRESPONDING FIELDS OF TABLE t_dd03l_req
       FROM dd03l
       WHERE tabname = c_tabname.

 

(3) Just for comparison, let us also include this combination of field list 
and INTO CORRESPONDING.

 

SELECT tabname
fieldname
reftable
       INTO CORRESPONDING FIELDS OF TABLE t_dd03l_req
       FROM dd03l
       WHERE tabname = c_tabname.

 

(4) Now switching to the full target structure, a combination of field 
list and INTO CORRESPONDING will likely not affect the run time, however more 
memory will be occupied this way.

 

SELECT tabname
fieldname
reftable
       INTO CORRESPONDING FIELDS OF TABLE t_dd03l_full
       FROM dd03l
       WHERE tabname = c_tabname.

 

(5) The combination of “*”, INTO CORRESPONDING and the full target structure 
must be avoided. This looks very similar to number 2 and probably helped 
leading to the bad image of this construct.


SELECT * INTO CORRESPONDING FIELDS OF TABLE t_dd03l_full
       FROM dd03l
       WHERE tabname = c_tabname.

 

(6) Of course there might be cases where you really need (almost) all of the 
columns of a table.

 

SELECT * INTO TABLE t_dd03l_full
       FROM dd03l
       WHERE tabname = c_tabname.
       
       
* Example from my own code:
  SELECT *
    INTO CORRESPONDING FIELDS OF TABLE gt_rf_out
    FROM fkkvkp AS vkp
    INNER JOIN fkkvk AS vk ON vkp~vkont = vk~vkont
	INNER JOIN but000 AS bt00 ON vkp~gpart = bt00~partner
	* INNER JOIN but0id AS bt0i ON vkp~gpart = bt0i~partner
	* INNER JOIN dfkkbptaxnum AS dtaxn ON vkp~gpart = dtaxn~partner


    WHERE vkp~vkont IN s_vkont
	* AND bt0i~type = 'FS0001'  
SELECT *
    INTO CORRESPONDING FIELDS OF TABLE gt_rf_out
    FROM fkkvkp AS vkp
    INNER JOIN fkkvk AS vk ON
      vkp~vkont = vk~vkont
*    inner join ever as e on
*      e~vkonto = vkp~vkont
    WHERE vkp~vkont IN s_vkont.
*    and e~loevm = ''.

  IF NOT gt_rf_out[] IS INITIAL.     "Για for all entries -- check line of table
    SELECT * INTO TABLE gt_ever
             FROM ever FOR ALL ENTRIES IN gt_rf_out
            WHERE vkonto = gt_rf_out-vkont
              AND loevm  = ''.
              
              
SORT gt_ever BY vkonto.                     " Sorting table  *1
    SORT gt_rf_out BY vkont.
    
    
    LOOP AT gt_rf_out ASSIGNING <fs_gt_rf_out>.

      READ TABLE gt_ever WITH KEY vkonto = <fs_gt_rf_out>-vkont
                         BINARY SEARCH.         " Sorting table  *1
      IF sy-subrc = 0.
        MOVE gt_ever-bstatus TO <fs_gt_rf_out>-bstatus.
        MOVE gt_ever-anlage  TO <fs_gt_rf_out>-anlage.
      ENDIF.


      READ TABLE lt_but000 ASSIGNING <lfs_but000>
                           WITH KEY partner = <fs_gt_rf_out>-gpart
                           BINARY SEARCH.
      IF sy-subrc = 0.
        IF <lfs_but000>-type = '1'.
          <fs_gt_rf_out>-name = <lfs_but000>-name_last.
          IF  <lfs_but000>-name_first IS NOT INITIAL AND
              <lfs_but000>-name_first(1) NE '.'.
            CONCATENATE <fs_gt_rf_out>-name <lfs_but000>-name_first
                   INTO <fs_gt_rf_out>-name
              SEPARATED BY space.
          ENDIF.
          IF <lfs_but000>-name_lst2 IS NOT INITIAL AND
             <lfs_but000>-name_lst2(1) NE '.'.
            CONCATENATE <fs_gt_rf_out>-name <lfs_but000>-name_lst2
                   INTO <fs_gt_rf_out>-name
              SEPARATED BY space.
          ENDIF.
        ELSEIF <lfs_but000>-type = '2'.
          <fs_gt_rf_out>-name = <lfs_but000>-name_org1.
        ENDIF.
      ENDIF.

      READ TABLE lt_but0id ASSIGNING <lfs_but0id>
                           WITH KEY partner = <fs_gt_rf_out>-gpart
                                    type    = 'FS0001'
                           BINARY SEARCH.
      IF sy-subrc = 0.
        <fs_gt_rf_out>-id = <lfs_but0id>-idnumber.
      ENDIF.

      READ TABLE lt_but0id ASSIGNING <lfs_but0id>
                           WITH KEY partner = <fs_gt_rf_out>-gpart
                                    type    = 'FS0002'
                           BINARY SEARCH.
      IF sy-subrc = 0.
        <fs_gt_rf_out>-passp = <lfs_but0id>-idnumber.
      ENDIF.

      READ TABLE lt_taxdoy ASSIGNING <lfs_taxdoy>
                           WITH KEY partner = <fs_gt_rf_out>-gpart
                                    taxtype = 'GR2'
                           BINARY SEARCH.
      IF sy-subrc = 0.
        <fs_gt_rf_out>-taxno = <lfs_taxdoy>-taxnum.
      ENDIF.

      READ TABLE lt_taxdoy ASSIGNING <lfs_taxdoy>
                           WITH KEY partner = <fs_gt_rf_out>-gpart
                                    taxtype = 'DOY'
                           BINARY SEARCH.
      IF sy-subrc = 0.
        <fs_gt_rf_out>-doy = <lfs_taxdoy>-taxnum.
      ENDIF.  



    LOOP AT gt_rf_out ASSIGNING <fs_gt_rf_out>.

      READ TABLE gt_ever WITH KEY vkonto = <fs_gt_rf_out>-vkont
                         BINARY SEARCH.         " Sorting table  *1
      IF sy-subrc = 0.
        MOVE gt_ever-bstatus TO <fs_gt_rf_out>-bstatus.
        MOVE gt_ever-anlage  TO <fs_gt_rf_out>-anlage.
      ENDIF.


      READ TABLE lt_but000 ASSIGNING <lfs_but000>
                           WITH KEY partner = <fs_gt_rf_out>-gpart
                           BINARY SEARCH.
      IF sy-subrc = 0.
        IF <lfs_but000>-type = '1'.
          <fs_gt_rf_out>-name = <lfs_but000>-name_last.
          IF  <lfs_but000>-name_first IS NOT INITIAL AND
              <lfs_but000>-name_first(1) NE '.'.
            CONCATENATE <fs_gt_rf_out>-name <lfs_but000>-name_first
                   INTO <fs_gt_rf_out>-name
              SEPARATED BY space.
          ENDIF.
          IF <lfs_but000>-name_lst2 IS NOT INITIAL AND
             <lfs_but000>-name_lst2(1) NE '.'.
            CONCATENATE <fs_gt_rf_out>-name <lfs_but000>-name_lst2
                   INTO <fs_gt_rf_out>-name
              SEPARATED BY space.
          ENDIF.
        ELSEIF <lfs_but000>-type = '2'.
          <fs_gt_rf_out>-name = <lfs_but000>-name_org1.
        ENDIF.
      ENDIF.

      READ TABLE lt_but0id ASSIGNING <lfs_but0id>
                           WITH KEY partner = <fs_gt_rf_out>-gpart
                                    type    = 'FS0001'
                           BINARY SEARCH.
      IF sy-subrc = 0.
        <fs_gt_rf_out>-id = <lfs_but0id>-idnumber.
      ENDIF.

      READ TABLE lt_but0id ASSIGNING <lfs_but0id>
                           WITH KEY partner = <fs_gt_rf_out>-gpart
                                    type    = 'FS0002'
                           BINARY SEARCH.
      IF sy-subrc = 0.
        <fs_gt_rf_out>-passp = <lfs_but0id>-idnumber.
      ENDIF.

      READ TABLE lt_taxdoy ASSIGNING <lfs_taxdoy>
                           WITH KEY partner = <fs_gt_rf_out>-gpart
                                    taxtype = 'GR2'
                           BINARY SEARCH.
      IF sy-subrc = 0.
        <fs_gt_rf_out>-taxno = <lfs_taxdoy>-taxnum.
      ENDIF.

      READ TABLE lt_taxdoy ASSIGNING <lfs_taxdoy>
                           WITH KEY partner = <fs_gt_rf_out>-gpart
                                    taxtype = 'DOY'
                           BINARY SEARCH.
      IF sy-subrc = 0.
        <fs_gt_rf_out>-doy = <lfs_taxdoy>-taxnum.
      ENDIF.
READ TABLE - result 


Quick Reference 

Syntax

... { INTO wa [transport_options] } 
  | { ASSIGNING <fs> [CASTING] } 
  | { REFERENCE INTO dref } 
  | { TRANSPORTING NO FIELDS }. 

Alternatives:

1. ... INTO wa [transport_options] 

2. ... ASSIGNING <fs> [CASTING] 

3. ... REFERENCE INTO dref 

4. ... TRANSPORTING NO FIELDS 

Programming Guideline

Output Behavior 

Effect

Defines the output behavior of a READ statement for an internal table. There are four alternatives for the output behavior: 
The addition INTO assigns the content of the found row to a work area. This addition can be used regardless of which way itab is specified. 

The addition ASSIGNING assigns the found row to a field symbol <fs>. This addition is possibly only if an existing internal table is specified for itab. 

The addition REFERENCE INTO creates a reference to the found row in a reference table. This addition is possibly only if an existing internal table is specified for itab. 

The addition TRANSPORTING NO FIELDS specifies that only the relevant system fields are filled. This addition can be used regardless of which way itab is specified. 


Note

Outside of classes, the addition INTO can also be specified together with TRANSPORTING NO FIELDS, but this produces a warning in the syntax check 

Alternative 1

... INTO wa [transport_options] 


Effect

The content of the found row is assigned to the work area wa. The following can be specified for wa:

An existing work area that matches the row type of the internal table. The row type must be compatible with the data type of the work area or must be able to be converted to this type. If the work area is incompatible with the row type of the internal table, the content of the table row is converted to the data type of the work area in accordance with the conversion rules. 

An inline declaration DATA(var), where a work area with the row type of the internal table is declared. The row type must be known statically and completely. 
If no row is found, wa remains unchanged or initial. If a conversion error occurs in the assignment to wa, the associated runtime error occurs directly and the exception cannot be handled using CX_SY_CONVERSION_ERROR.

If the additions transport_options are used, the work area wa must be compatible with the row type of the internal table. 

Note

For READ TABLE, an (external) obsolete short form exists where INTO wa can be omitted if the internal table has a header line itab with the same name. The statement is then implicitly enhanced by the addition of INTO itab. This short form is unrelated to the obsolete key specification, which also evaluates the header line. 

Example

Reads a particular row in the internal table sflight_tab and assigns it to a work area sflight_wa (declared inline). After the reference has been successfully assigned, the content of a component of the row is changed in the internal table.

DATA: carrid TYPE sflight-carrid, 
      connid TYPE sflight-connid, 
      fldate TYPE sflight-fldate. 

... 

DATA sflight_tab TYPE SORTED TABLE OF sflight 
                 WITH UNIQUE KEY carrid connid fldate. 

SELECT * 
       FROM sflight 
       WHERE carrid = @carrid AND 
             connid = @connid 
       INTO TABLE @sflight_tab. 

IF sy-subrc = 0. 
  READ TABLE sflight_tab 
       WITH TABLE KEY carrid = carrid 
                      connid = connid 
                      fldate = fldate 
       INTO DATA(sflight_wa). 
  IF sy-subrc = 0. 
    sflight_wa-price = sflight_wa-price * '0.9'. 
    MODIFY sflight_tab FROM sflight_wa INDEX sy-tabix. 
  ENDIF. 
ENDIF. 


Alternative 2

... ASSIGNING <fs> [CASTING] 


Effect

The found table row is assigned to a field symbol. After the statement READ TABLE, the field symbol points to the table row in the memory. The addition cannot be specified if itab is specified as the return value or result of a functional method, a constructor expression, or a table expression, since this value no longer exists once the statement has been executed.

The following can be specified for <fs>:

An existing field symbol whose typing matches the row type of the internal table. The optional addition CASTING can be used to perform a casting. It has the same meaning as if it were specified in the statement ASSIGN: The field symbol must be either fully typed, or typed with one of the generic predefined ABAP types c, n, p, or x. The assigned table row is cast to the type of the field symbol. The same exceptions can be raised here as with ASSIGN. 

An inline declaration FIELD-SYMBOL(<fs>), where a field symbol with the row type of the internal table is declared. The inline declaration cannot be specified after the addition CASTING. 
If no table row is found, <fs> remains unchanged or initial.

As long as the field symbol points to the row, assignments to the field symbol modify the row in the internal table. The following limitations apply to modifying key fields of the primary and secondary table key:

The key fields of the primary table key of sorted tables and hashed tables are read-only and must not be modified. This would invalidate internal table administration. The processing statements for internal tables check whether writes are performed on individual key fields and a corresponding non-handleable exception raised. If writes are performed in write positions across the entire table row (for example, as a target field of assignments or as actual parameters for output parameters), an exception is always raised. 

The key fields of a secondary table key, however, are only read-only while the secondary table is being used. This is the case in LOOP loops and during the use of the MODIFY statement, in which the secondary key is specified after USING KEY. Otherwise the key fields are not read-only. 
The administration of unique secondary keys is updated after modifications are made to individual rows using field symbols the next time the internal table is accessed (delayed update). The administration of non-unique secondary keys is updated after the next explicit use of the secondary key (lazy update). The check on the uniqueness of a secondary key does not take place until the time of the update. An internal table might therefore be in an inconsistent state with respect to the secondary key after individual rows are modified using field symbols. An exception is not raised until the table is next used. If the next use is not directly after the modification, the secondary key can be explicitly updated using methods of the CL_ABAP_ITAB_UTILITIES class to handle possible exceptions on the spot. 

Notes

The typing of the field symbol must be compatible with the row type of the internal table. 

If the READ statement is successful (sy-subrc has value 0), it is guaranteed that the field symbol immediately after execution of the statement indicates a memory area. A query using IS ASSIGNED is not necessary there. 

If the row to which the field symbol points is deleted, no more memory space is allocated to the field symbol and it can no longer be used instead of a data object. If the field symbol is not used directly after the READ statement, it may be useful to carry out a check using IS ASSIGNED. 

Another form of the statement READ TABLE using the addition ASSIGNING is a table expression table_exp specified after the statement ASSIGN. 


Example

Selects a particular row in the internal table sflight_tab and assigns it to a field symbol <sflight> (declared inline). After the reference has been successfully assigned, the content of a component of the row is changed in the internal table. See also the example of the assignment of a table expression to a field symbol.

DATA: carrid TYPE sflight-carrid, 
      connid TYPE sflight-connid, 
      fldate TYPE sflight-fldate. 

... 

DATA sflight_tab TYPE SORTED TABLE OF sflight 
                 WITH UNIQUE KEY carrid connid fldate. 

SELECT * 
       FROM sflight 
       WHERE carrid = @carrid AND 
             connid = @connid 
       INTO TABLE @sflight_tab. 

IF sy-subrc = 0. 
  READ TABLE sflight_tab 
       WITH TABLE KEY carrid = carrid 
                      connid = connid 
                      fldate = fldate 
       ASSIGNING FIELD-SYMBOL(<sflight>). 
  IF sy-subrc = 0. 
     <sflight>-price = <sflight>-price * '0.9'. 
  ENDIF. 
ENDIF. 


Alternative 3

... REFERENCE INTO dref 


Effect

A reference to the found table row is made in the data reference variable dref. The addition cannot be specified if itab is specified as the return value or result of a functional method or of a table expression of a constructor expression, since this value no longer exists once the statement has been executed.

The following can be specified for dref:

An existing data reference variable whose static type is compatible with the row type of the internal table or is the generic type data. 

An inline declaration DATA(var), where a data reference variable is declared whose static type is the row type of the internal table. The row type must be known statically and completely. 
If no table row is found, dref remains unchanged or initial.

By dereferencing the data reference, the content of the found table row can be evaluated and changed. The same limitations apply to the modification of key fields of the primary and secondary table key as for access using field symbols (see ASSIGNING addition). 

Notes

If the READ statement is successful (sy-subrc has value 0), it is guaranteed that the data reference variable immediately after the execution of the statement indicates a row. A query using IS BOUND is not necessary here. 

Alongside GET REFERENCE and the reference operator REF, REFERENCE INTO is the only way of creating stack references. Stack references can become invalid if the referenced data object is deleted. 

When applied to internal tables in the heap REFERENCE INTO creates memory-retaining heap references. 

All references (heap references and stack references) that point to rows from internal tables can become invalid when rows are deleted. If a data reference variable is not used directly after the READ statement, it may be useful to carry out a check using IS BOUND. 


Example

Selects a particular row of the internal table sflight_tab and assigns a reference to the found row to the data reference variable sflight_ref (declared inline). After the reference has been successfully assigned, the content of a component of the row is changed in the internal table.

DATA: carrid TYPE sflight-carrid, 
      connid TYPE sflight-connid, 
      fldate TYPE sflight-fldate. 

... 

DATA sflight_tab TYPE SORTED TABLE OF sflight 
                 WITH UNIQUE KEY carrid connid fldate. 

SELECT * 
       FROM sflight 
       WHERE carrid = @carrid AND 
             connid = @connid 
       INTO TABLE @sflight_tab. 

IF sy-subrc = 0. 
  READ TABLE sflight_tab 
       WITH TABLE KEY carrid = carrid 
                      connid = connid 
                      fldate = fldate 
            REFERENCE INTO DATA(sflight_ref). 

  IF sy-subrc = 0. 
    sflight_ref->price = sflight_ref->price * '0.9'. 
  ENDIF. 
ENDIF. 


Alternative 4

... TRANSPORTING NO FIELDS 


Effect

If the addition TRANSPORTING NO FIELDS is used, the statement READ TABLE only checks whether the row that is being searched for exists, and fills the system fields sy-subrc and sy-tabix. The system cannot access the content of the found row.

Notes

The predicate function line_exists can also be used to check the existence of a table row. 

The table function line_index can also be used to identify the row number in the table index. 


Example

Checks whether a particular row exists in the internal table sflight_carr and assigns the row number in the primary table index of the found row in sy-tabix to idx.

DATA carrid TYPE scarr-carrid. 

... 

DATA: scarr_tab TYPE SORTED TABLE OF scarr 
                WITH UNIQUE KEY carrid, 
      idx  TYPE i. 

SELECT * 
       FROM scarr 
       INTO TABLE @scarr_tab. 

READ TABLE scarr_tab 
     WITH TABLE KEY carrid = carrid 
     TRANSPORTING NO FIELDS. 
IF sy-subrc = 0. 
  idx = sy-tabix. 
ENDIF. 
SELECT - SINGLE 


Quick Reference 

Syntax

... SINGLE [FOR UPDATE] ... 

Addition:

... FOR UPDATE 

Effect

The ABAP-specific addition SINGLE makes the results set of a query a single row set. The addition is possible with a standalone SELECT statement or with the main query of a standalone WITH statement. If SINGLE is specified, these statements does not open a loop closed using ENDSELECT or ENDWITH during imports to a non-table-like target area, and no internal tables can be specified as a target area.

If the selection of the SELECT statement covers precisely one row, this row is included in the results set. 

If the selection of the SELECT statement covers more than one row, one of these rows is included in the results set at random. 
The following restrictions apply:

The additions FOR ALL ENTRIES, ORDER BY, and UP TO cannot be used together with SINGLE. 

Addition SINGLE cannot be used in the main query of statement OPEN CURSOR or in subqueries. 


Notes

The addition SINGLE is designed to pass precisely one row to a flat structure as a work area without opening a loop closed using ENDSELECT or ENDWITH. 
Usually, the row must be identified precisely and it must be specified uniquely in the WHERE condition. In a data source, this is usually done by specifying comparison values for the primary key. The extended program check produces a warning if no precise row is identified.
If no unique row is identified, the addition SINGLE can also be used to detect whether a corresponding row exists. In this case, the warning from the extended program check must be hidden using a pragma. To avoid unnecessary transports of data, a SELECT list can also be used that contains nothing but a single constant (see the executable example).
In the case of rows specified in full, a SELECT statement with the addition SINGLE is generally faster than specifying only part of the row.
The results set of SELECT statements with the addition SINGLE matches the set from the addition UP TO 1 ROWS without using the addition ORDER BY. 
If the addition SINGLE is used, it is not necessary to use the statements ENDSELECT, ENDWITH or to import the row into an internal table. Not all additions of the SELECT statement, however, can be used.
If the addition UP TO 1 ROWS is used, the statement ENDSELECT or ENDWITH must be specified or the row must be imported into an internal table. The addition ORDER BY can, however, be specified.
A SELECT statement with the addition SINGLE can be optimized for reading a single row, which means is generally somewhat faster than when using the addition UP TO 1 ROWS. In practice, however, this difference can usually be ignored. In light of this, the following is recommended:
Use of the addition SINGLE to read a row specified in full precisely.
Use of the addition UP TO 1 ROWS to read a maximum of one row from a set of selected rows.
The addition ORDER BY cannot be used together with SINGLE, which means that it is not possible to define which row is read from a non-unique selection. Instead, the addition UP TO 1 ROWS can be specified with the addition ORDER BY to define which row is read from a non-unique selection. 

If SINGLE is specified and LOB handles are created in the INTO clause, all primary key fields joined by AND in logical expressions must be checked for equivalence in the WHERE condition. If this is not possible, the addition UP TO 1 ROWS can be used instead of SINGLE. 

If the addition SINGLE is used, after the creation of LOB handles, all reader streams which are created when executing the statement SELECT, as well as locators, continue to exist until they are closed, either explicitly with one of their methods, or implicitly at the end of the current database LUW. The associated database operation is not completed during this time. It is best to close all LOB handles as soon as possible. 
Example

Reads the row with the information about Lufthansa flight 0400 from the database table SPFLI.

DATA wa TYPE spfli. 

SELECT SINGLE * 
       FROM spfli 
       WHERE carrid = 'LH' AND 
             connid = '0400' 
       INTO CORRESPONDING FIELDS OF @wa. 


Example

The program DEMO_SELECT_SINGLE_VS_UP_TO compares the performance of SELECT statements with the addition SINGLE with similar statements with the addition UP TO 1 ROWS. 

Addition

... FOR UPDATE 
Effect

When reading an individual row using SINGLE, the addition FOR UPDATE sets an exclusive lock for this row on the database. The statement SELECT is then only executed if, in the WHERE condition, all primary key fields in logical expression which are joined using AND are checked for equivalence. Otherwise the results set is empty and sy-subrc is set to 8. If setting the lock produces a deadlock, an exception is raised. If the addition FOR UPDATE is used, a SELECT statement bypasses SAP buffering. 




*&---------------------------------------------------------------------*
*& Report  ZTEE_ITAB_ALL_EXPL
*&
*&---------------------------------------------------------------------*
*& Details various way and declare itab and their uses:
*&
*&    1. LIKE <dbtable>
*&    2. LIKE <dbtable> with header line/work area.
*&
*&    3. BEGIN/OCCURS/TYPE declare specific fields
*&    4. BEGIN/OCCURS/TYPE declare specific fields w/ separate header line/work area.
*&
*&    5. BEGIN/TYPE STANDARD TABLE declare specific fields using TYPES
*&    6. BEGIN/TYPE STANDARD TABLE declare specific fields using TYPES w/ separate header line.
*&
*&    7. LIKE/OCCURS declare itab from existing itab
*&    8. LIKE/OCCURS declare itab from existing itab w/ separate header line/work area.
*&
*&    9. BEGIN/INCLUDE STRUCTURE declare itab including structure of db table
*&    10.BEGIN/INCLUDE STRUCTURE declare itab including structure of db table w/ separate header line.
*&
*&    11.BEGIN/INCLUDE STRUCTURE declare itab including structure of another itab
*&    12.BEGIN/INCLUDE STRUCTURE declare itab including structure of another itab w/ separate header line.
*&
*&    13.BEGIN/INCLUDE STRUCTURE declare itab including structure of a dbtable and extra fields
*&    14.BEGIN/INCLUDE STRUCTURE declare itab including structure of a dbtable and extra fields w/ header line
*&
*&    15.BEGIN/INCLUDE STRUCTURE declare itab including structure of a itab and extra fields
*&    16 BEGIN/INCLUDE STRUCTURE declare itab including structure of a itab and extra fields w/ header line
*&
*&    17.BEGIN/TYPES declare itab using TYPES and only specific fields
*&    18.   Specific unique key / Sorted
*&    19    Specific unique key / Sorted /w header line
*&    20.   Default unique key / Sorted
*&    21.   Default unique key / Sorted /w header line
*&    22.   Specific unique key / Hashed
*&    23.   Specific unique key / Hashed /w header line
*&    24.   Default unique key / Hashed
*&    25.   Default unique key / Hashed /w header line
*&---------------------------------------------------------------------*

REPORT  ZTEE_ITAB_ALL_EXPL.






********************************************************************
* TYPES OF DECLARATIONS

"" Declare using LIKE + work area/header line separately
DATA: gt_ever LIKE EVER OCCURS 0.
DATA: wa_gt_ever LIKE LINE OF gt_ever.

"" Declare using LIKE + work area/header line inline
DATA: gs_ever LIKE ever OCCURS 0 WITH HEADER LINE.

"" Declare specific structure + work area inline
DATA: BEGIN OF gb_ever OCCURS 0,
      bstatus TYPE ever-bstatus,
      vrefer  TYPE ever-vrefer,
 END OF gb_ever.

"" Declare specific structure + work area separately
DATA: BEGIN OF gu_ever OCCURS 0,
      bstatus TYPE ever-bstatus,
      vkonto  TYPE ever-vkonto,
 END OF gu_ever.

DATA: wa_gu_ever LIKE LINE OF gu_ever.

"" Declare using TYPES
TYPES: BEGIN OF g_ever,
  bstatus TYPE ever-bstatus,
  vkonto TYPE ever-vkonto,
 END OF g_ever.
DATA: ga_ever TYPE STANDARD TABLE OF g_ever INITIAL SIZE 0 WITH HEADER LINE.     "itab
"      wa_ekpo TYPE t_ekpo.                    "work area (header line)

"" Declare using TYPES + work area separately
DATA: gi_ever TYPE STANDARD TABLE OF g_ever INITIAL SIZE 0,
      wa_gi_ever TYPE g_ever.                    "work area (header line)



"" Declare itab from existing internal table (FOR THIS TO WORK ga_Ever needs to be declared with header line)
"" If it is declared with separate work area instead of LIKE <itab> use LIKE <wa_itab>
DATA: gy_ever LIKE ga_ever OCCURS 0 WITH HEADER LINE.

"" Declare itab from existing internal table with separate header line (FOR THIS TO WORK ga_ever needs to be declared with header line)
DATA: gq_ever LIKE ga_ever OCCURS 0.
DATA: wa_gq_ever LIKE LINE OF gq_ever.



"" Declare itab using INCLUDE <dbtable>
"" dbtables always have a structure, so no case of getting "No structure" error.
TYPES: BEGIN OF combi_struct1.
        INCLUDE STRUCTURE ever.
TYPES: END OF combi_struct1.

DATA: combi_tab1 TYPE STANDARD TABLE OF combi_struct1 INITIAL SIZE 0,
      wa_combi_tab1  TYPE combi_struct1.

DATA: combi_tab2 TYPE STANDARD TABLE OF combi_struct1 INITIAL SIZE 0 WITH HEADER LINE.



"" Declare itab using INCLUDE <itab>
"" For this to work itab needs to be declared with header line or have a specified structure.
"" Using <itab> declared with: DATA: gq_ever LIKE ga_ever OCCURS 0. will result in "Include doesnt have structure error"
"" TO RESOLVE THIS WE NEED TO: INCLUDE STRUCTURE <work_area> of the table we have declared.
TYPES: BEGIN OF combi_struct2.
        INCLUDE STRUCTURE ga_ever.
" INCLUDE STRUCTURE gq_ever -> This hits error.
TYPES: END OF combi_struct2.

DATA: combi_itab1 TYPE STANDARD TABLE OF combi_struct2 INITIAL SIZE 0,
      wa_combi_itab1 TYPE combi_struct2.

DATA: combi_itab2 TYPE STANDARD TABLE OF combi_struct2 INITIAL SIZE 0 WITH HEADER LINE.


"" Declare itab using INCLUDE <dbtable> + Extra Fields
TYPES: BEGIN OF combi_struct3.
        INCLUDE STRUCTURE ever.
TYPES: vkont TYPE fkkvk-vkont,
       bstatusother TYPE ever-bstatus.
TYPES: END OF combi_struct3.

DATA: combi_itab3 TYPE STANDARD TABLE OF combi_struct3 INITIAL SIZE 0,
      wa_combi_itab3 TYPE combi_struct3.

DATA: combi_itab4 TYPE STANDARD TABLE OF combi_struct3 INITIAL SIZE 0 WITH HEADER LINE.


"" Declare itab using INCLUDE <itab> + Extra Fields
TYPES: BEGIN OF combi_struct4.
        INCLUDE STRUCTURE ga_ever.
TYPES: vkont TYPE fkkvk-vkont,
       bstatusother TYPE ever-bstatus.
TYPES: END OF combi_struct4.


DATA: combi_itab5 TYPE STANDARD TABLE OF combi_struct4 INITIAL SIZE 0,
      wa_combi_itab5 TYPE combi_struct4.


DATA: combi_itab6 TYPE STANDARD TABLE OF combi_struct4 INITIAL SIZE 0 WITH HEADER LINE.


"" Declare itab using TYPES and only specific fields
TYPES: BEGIN OF combi_struct5.
TYPES:  vkonto TYPE ever-vkonto,
        bstatus TYPE ever-bstatus.
TYPES: END OF combi_struct5.

DATA: combi_itab7 TYPE STANDARD TABLE OF combi_struct5 INITIAL SIZE 0,
      wa_combi_itab7 TYPE combi_struct5.

DATA: combi_itab8 TYPE STANDARD TABLE OF combi_struct5 INITIAL SIZE 0 WITH HEADER LINE.



"" Declare itab using TYPES and UNIQUE/NON-UNIQUE KEY
TYPES: BEGIN OF combi_struct6.
  INCLUDE STRUCTURE wa_gt_ever.
TYPES: END OF combi_struct6.

" UNIQUE KEY ONLY WORKS WITH SORTED AND HASHED TABLES.
" Specific unique key - Will produce an error if there are duplicate values in the field. ( SORTED TABLE)
DATA: combi_itab9 TYPE SORTED TABLE OF combi_struct6 WITH UNIQUE KEY vertrag WITH HEADER LINE.

DATA: combi_itab10 TYPE SORTED TABLE OF combi_struct6 WITH UNIQUE KEY vertrag.
DATA: wa_combi_itab10 TYPE combi_struct6.

" Default unique key - as declared in se11 ( SORTED TABLE )
DATA: combi_itab11 TYPE SORTED TABLE OF combi_struct6 WITH UNIQUE DEFAULT KEY WITH HEADER LINE.

DATA: combi_itab12 TYPE SORTED TABLE OF combi_struct6 WITH UNIQUE DEFAULT KEY.
DATA: wa_combi_itab12 TYPE combi_struct6.

*
" Specific unique key - Will produce an error if there are duplicate values in the field. ( SORTED TABLE)
DATA: combi_itab13 TYPE HASHED TABLE OF combi_struct6 WITH UNIQUE KEY vertrag WITH HEADER LINE.

DATA: combi_itab14 TYPE HASHED TABLE OF combi_struct6 WITH UNIQUE KEY vertrag.
DATA: wa_combi_itab14 TYPE combi_struct6.

" Default unique key - as declared in se11 ( SORTED TABLE )
DATA: combi_itab15 TYPE HASHED TABLE OF combi_struct6 WITH UNIQUE DEFAULT KEY WITH HEADER LINE.

DATA: combi_itab16 TYPE HASHED TABLE OF combi_struct6 WITH UNIQUE DEFAULT KEY.
DATA: wa_combi_itab16 TYPE combi_struct6.


********************************************************
* POPULATING THE ABOVE TABLES
SELECT *
  INTO CORRESPONDING FIELDS OF TABLE gt_ever
  FROM ever.

SELECT *
  INTO CORRESPONDING FIELDS OF TABLE gs_ever
  FROM ever.

SELECT *
  INTO CORRESPONDING FIELDS OF TABLE gb_ever
  FROM ever.

SELECT *
  INTO CORRESPONDING FIELDS OF TABLE gu_ever
  FROM ever.

SELECT *
  INTO CORRESPONDING FIELDS OF TABLE ga_ever
  FROM ever.

SELECT *
  INTO CORRESPONDING FIELDS OF TABLE gb_ever
  FROM ever.

SELECT *
  INTO CORRESPONDING FIELDS OF TABLE gi_ever
  FROM ever.

SELECT *
  INTO CORRESPONDING FIELDS OF TABLE gy_ever
  FROM ever.

SELECT *
  INTO CORRESPONDING FIELDS OF TABLE gq_ever
  FROM ever.

SELECT *
  INTO CORRESPONDING FIELDS OF TABLE combi_tab1
  FROM ever.

SELECT *
  INTO CORRESPONDING FIELDS OF TABLE combi_tab2
  FROM ever.

SELECT *
  INTO CORRESPONDING FIELDS OF TABLE combi_itab1
  FROM ever.

SELECT *
  INTO CORRESPONDING FIELDS OF TABLE combi_itab2
  FROM ever.

SELECT *
  INTO CORRESPONDING FIELDS OF TABLE combi_itab3
  FROM ever.

" Using a second select to populate new field vkont - This doesnt work (why?)
*SELECT vkont
*  FROM FKKVK
*  INTO CORRESPONDING FIELDS OF TABLE combi_itab3
*  FOR ALL ENTRIES IN combi_itab3
*  WHERE vkont = combi_itab3-vkonto.

SELECT *
  INTO CORRESPONDING FIELDS OF TABLE combi_itab4
  FROM ever.

" Using a second select to populate new field vkont
SELECT vkont
  FROM FKKVK
  INTO CORRESPONDING FIELDS OF TABLE combi_itab4
  FOR ALL ENTRIES IN combi_itab4
  WHERE vkont = combi_itab4-vkonto.

SELECT *
  INTO CORRESPONDING FIELDS OF TABLE combi_itab5
  FROM ever.

SELECT *
  INTO CORRESPONDING FIELDS OF TABLE combi_itab6
  FROM ever.

SELECT *
  INTO CORRESPONDING FIELDS OF TABLE combi_itab7
  FROM ever.

SELECT *
  INTO CORRESPONDING FIELDS OF TABLE combi_itab8
  FROM ever.

SELECT *
  INTO CORRESPONDING FIELDS OF TABLE combi_itab9
  FROM ever.

SELECT *
  INTO CORRESPONDING FIELDS OF TABLE combi_itab10
  FROM ever.

SELECT *
  INTO CORRESPONDING FIELDS OF TABLE combi_itab11
  FROM ever.

SELECT *
  INTO CORRESPONDING FIELDS OF TABLE combi_itab12
  FROM ever.

SELECT *
  INTO CORRESPONDING FIELDS OF TABLE combi_itab13
  FROM ever.

SELECT *
  INTO CORRESPONDING FIELDS OF TABLE combi_itab14
  FROM ever.

SELECT *
  INTO CORRESPONDING FIELDS OF TABLE combi_itab15
  FROM ever.

SELECT *
  INTO CORRESPONDING FIELDS OF TABLE combi_itab16
  FROM ever.

***********************************************************
* CHECKING IF TABLES HAVE CONTENT LOADED
IF gt_ever[] IS INITIAL.
  WRITE: / 'Problem loading gt_ever'.
ELSE.
  WRITE: / 'Success loading gt_ever'.
ENDIF.

IF gs_ever[] IS INITIAL.
  WRITE: / 'Problem loading gs_ever'.
ELSE.
  WRITE: / 'Success loading gs_ever'.
ENDIF.

IF gb_ever[] IS INITIAL.
  WRITE: / 'Problem loading gs_ever'.
ELSE.
  WRITE: / 'Success loading gs_ever'.
ENDIF.

IF gu_ever[] IS INITIAL.
  WRITE: / 'Problem loading gs_ever'.
ELSE.
  WRITE: / 'Success loading gs_ever'.
ENDIF.

IF ga_ever[] IS INITIAL.
  WRITE: / 'Problem loading gs_ever'.
ELSE.
  WRITE: / 'Success loading ga_ever'.
ENDIF.

IF gb_ever[] IS INITIAL.
  WRITE: / 'Problem loading gs_ever'.
ELSE.
  WRITE: / 'Success loading ga_ever'.
ENDIF.

IF gi_ever[] IS INITIAL.
  WRITE: / 'Problem loading gs_ever'.
ELSE.
  WRITE: / 'Success loading ga_ever'.
ENDIF.

IF gy_ever[] IS INITIAL.
  WRITE: / 'Problem loading gs_ever'.
ELSE.
  WRITE: / 'Success loading ga_ever'.
ENDIF.

IF gq_ever[] IS INITIAL.
  WRITE: / 'Problem loading gs_ever'.
ELSE.
  WRITE: / 'Success loading ga_ever'.
ENDIF.

IF combi_tab1[] IS INITIAL.
  WRITE: / 'Problem loading gs_ever'.
ELSE.
  WRITE: / 'Success loading ga_ever'.
ENDIF.

IF combi_tab2[] IS INITIAL.
  WRITE: / 'Problem loading gs_ever'.
ELSE.
  WRITE: / 'Success loading ga_ever'.
ENDIF.

IF combi_itab1[] IS INITIAL.
  WRITE: / 'Problem loading gs_ever'.
ELSE.
  WRITE: / 'Success loading ga_ever'.
ENDIF.

IF combi_itab2[] IS INITIAL.
  WRITE: / 'Problem loading gs_ever'.
ELSE.
  WRITE: / 'Success loading ga_ever'.
ENDIF.

IF combi_itab3[] IS INITIAL.
  WRITE: / 'Problem loading gs_ever'.
ELSE.
  WRITE: / 'Success loading ga_ever'.
ENDIF.

IF combi_itab4[] IS INITIAL.
  WRITE: / 'Problem loading combi_itab4'.
ELSE.
  WRITE: / 'Success loading combi_itab4'.
ENDIF.

IF combi_itab5[] IS INITIAL.
  WRITE: / 'Problem loading combi_itab5'.
ELSE.
  WRITE: / 'Success loading combi_itab5'.
ENDIF.

IF combi_itab6[] IS INITIAL.
  WRITE: / 'Problem loading combi_itab5'.
ELSE.
  WRITE: / 'Success loading combi_itab5'.
ENDIF.

IF combi_itab7[] IS INITIAL.
  WRITE: / 'Problem loading combi_itab7'.
ELSE.
  WRITE: / 'Success loading combi_itab7'.
ENDIF.

IF combi_itab8[] IS INITIAL.
  WRITE: / 'Problem loading combi_itab8'.
ELSE.
  WRITE: / 'Success loading combi_itab8'.
ENDIF.

IF combi_itab9[] IS INITIAL.
  WRITE: / 'Problem loading combi_itab9'.
ELSE.
  WRITE: / 'Success loading combi_itab9'.
ENDIF.


IF combi_itab10[] IS INITIAL.
  WRITE: / 'Problem loading combi_itab9'.
ELSE.
  WRITE: / 'Success loading combi_itab9'.
ENDIF.

IF combi_itab11[] IS INITIAL.
  WRITE: / 'Problem loading combi_itab9'.
ELSE.
  WRITE: / 'Success loading combi_itab9'.
ENDIF.

IF combi_itab12[] IS INITIAL.
  WRITE: / 'Problem loading combi_itab9'.
ELSE.
  WRITE: / 'Success loading combi_itab9'.
ENDIF.


IF combi_itab13[] IS INITIAL OR
   combi_itab14[] IS INITIAL OR
   combi_itab15[] IS INITIAL OR
   combi_itab16[] IS INITIAL.
  WRITE: / 'Problem loading hashed tables'.
ELSE.
  WRITE: / ' Success loading hashed tables'.
ENDIF.


*****************************************************
* LOOPING ASSIGNING AND WRITING

"LOOP AT gt_ever INTO wa_gt_ever.
"  WRITE: / wa_gt_ever-bstatus.
"ENDLOOP.

*LOOP AT gs_ever.
*  WRITE: / gs_ever-bstatus.
*ENDLOOP.

*LOOP AT gb_ever.
*  WRITE: / gb_ever-bstatus.
*ENDLOOP.

*LOOP AT gt_ever INTO wa_gu_ever.
*  WRITE: / wa_gu_ever-vkonto.
*ENDLOOP.

*LOOP AT gi_ever INTO wa_gi_ever.
*  WRITE: / wa_gi_ever-vkonto.
*ENDLOOP.

*LOOP AT gy_ever.
*  WRITE: / gy_ever-vkonto.
*ENDLOOP.

*LOOP AT gq_ever INTO wa_gq_ever.
*  WRITE: / wa_gq_ever-vkonto.
*ENDLOOP.

*LOOP AT combi_tab1 INTO wa_combi_tab1.
*  WRITE: / wa_combi_tab1-vkonto.
*ENDLOOP.

*LOOP AT combi_tab2.
*  WRITE: / combi_tab2-vkonto.
*ENDLOOP.

*LOOP AT combi_itab1 INTO wa_combi_itab1.
*  WRITE: / wa_combi_itab1-vkonto.
*ENDLOOP.

*LOOP AT combi_itab2.
*  WRITE: / combi_itab2-vkonto.
*ENDLOOP.

*LOOP AT combi_itab3 INTO wa_combi_itab3.
*  WRITE: / wa_combi_itab3-vkonto.
*ENDLOOP.

*LOOP AT combi_itab4
*   WHERE vkont <> combi_itab4-vkonto.
*  WRITE: / 'Not Found', combi_itab4-vkont, combi_itab4-vkonto.
*ENDLOOP.

*LOOP AT combi_itab5 INTO wa_combi_itab5.
*  WRITE: / wa_combi_itab5-vkonto.
*ENDLOOP.

*LOOP AT combi_itab6.
*  WRITE: / combi_itab6-vkonto.
*ENDLOOP.


*LOOP AT combi_itab7 INTO wa_combi_itab7.
*  WRITE: / wa_combi_itab7-vkonto.
*ENDLOOP.

*LOOP AT combi_itab8.
*  WRITE: / combi_itab8-vkonto.
*ENDLOOP.


*LOOP AT combi_itab9.
*  WRITE: / combi_itab9-vkonto.
*ENDLOOP.

*LOOP AT combi_itab10 INTO wa_combi_itab10.
*  WRITE: / wa_combi_itab10-vkonto.
*ENDLOOP.

*LOOP AT combi_itab11.
*  WRITE: / combi_itab11-vkonto.
*ENDLOOP.

*LOOP AT combi_itab13..
*  WRITE: / combi_itab13-vkonto.
*ENDLOOP.

*LOOP AT combi_itab14 INTO wa_combi_itab14.
*  WRITE: / wa_combi_itab14-vkonto.
*ENDLOOP.

*LOOP AT combi_itab15.
*  WRITE: / combi_itab15-vkonto.
*ENDLOOP.

LOOP AT combi_itab16 INTO wa_combi_itab16.
  WRITE: / wa_combi_itab16-vkonto.
ENDLOOP.