SQL SELECT

Getting started ... Alles für einen gelungenen Start.
7 Beiträge • Seite 1 von 1
7 Beiträge Seite 1 von 1

SQL SELECT

Beitrag von rob_abc (Specialist / 107 / 27 / 44 ) »
Hallo zusammen

Kann man folgende SQLs auch in einer Abfrage ausdrücken? Ziel ist, alle 5 Datensätze direkt in der internen Tabelle zu haben, nicht nur drei. Irgendwie stehe ich auf dem Schlauch und weiss nicht so recht wonach googeln.

Code: Alles auswählen.

REPORT.

TYPES:
  BEGIN OF ty_db,
    id    TYPE i,
    model TYPE char20,
    farbe TYPE char20,
  END OF ty_db,
  tty_db TYPE STANDARD TABLE OF ty_db WITH EMPTY KEY.

DATA g_db TYPE tty_db.
g_db = VALUE #(
  ( id = '1' Model = 'Golf' Farbe = 'Rot' )
  ( id = '1' Model = 'Gold' Farbe = 'Blau' )
  ( id = '2' Model = 'Passat' Farbe = 'Rot' )
  ( id = '2' Model = 'Passat' Farbe = 'Weiss' )
  ( id = '3' Model = 'Polo' Farbe = 'Schwarz' )
  ( id = '3' Model = 'Polo' Farbe = 'Blau' )
  ( id = '4' Model = 'Tiguan' Farbe = 'Lila' )
  ( id = '5' Model = 'GTI' Farbe = 'Rot' ) ).

"SQL für die Farbe Rot. Aber die anderen Einträge mit gleicher ID sollen ebenfalls
"in der Ergebnismenge stehen
SELECT * FROM @g_db AS itab
  WHERE farbe = 'Rot'
  INTO TABLE @DATA(g_red).

DATA(l_red_ids) = VALUE rsdsselopt_t( FOR <line> IN g_red
( sign = 'I' option = 'EQ' low = <line>-id ) ).

"daher ein zweiter Select :(
SELECT * FROM @g_db AS itab
  WHERE id IN @l_red_ids
  INTO TABLE @DATA(g_found_entries).

cl_demo_output=>display( g_found_entries ).

gesponsert
Stellenangebote auf ABAPforum.com schalten
kostenfrei für Ausbildungsberufe und Werksstudenten


Re: SQL SELECT

Beitrag von ewx (Top Expert / 4849 / 313 / 642 ) »
Bei einer DB-Tabelle müsste es mit einem Subquery gehen:

Code: Alles auswählen.

select * from @g_db as db
  where id in ( SELECT id from g_Db where farbe = 'Rot' ).
Bei deinem Beispiel mit dem Select auf die interne Tabelle funktioniert es allerdings nicht.

Folgende Benutzer bedankten sich beim Autor ewx für den Beitrag:
rob_abc


Re: SQL SELECT

Beitrag von rob_abc (Specialist / 107 / 27 / 44 ) »
Ah, sehr gut. Funktioniert auf der DB, vielen Dank. Hab mich schon immer gefragt, wofür man sub selects brauchen kann :D

Noch eine kurze Anschlussfrage. Wenn ich nur Autos in Rot UND Blau haben möchte, also nur ID 1 kommt zurück, wie kann ich das ausdrücken?

so scheint es auf den ersten Blick zu funktionieren:

Code: Alles auswählen.

select * from @g_db as db
  where id in ( SELECT id from g_Db where farbe = 'Rot' )
    AND id in ( SELECT id from g_Db where farbe = 'Blau' ).

Re: SQL SELECT

Beitrag von ewx (Top Expert / 4849 / 313 / 642 ) »
Theoretisch müsste auch ein JOIN im Subquery möglich sein. Habe es aber eben syntaktisch nicht hinbekommen... :(

Code: Alles auswählen.

    SELECT * FROM @db AS db
      INTO @DATA(test)
     WHERE e~id IN (
       SELECT id FROM db AS d1
                 INNER JOIN db AS d2
              ON d1~id = d2~id
               WHERE d1~farbe = 'Rot'
                 AND d2~farbe = 'Blau' ).

Re: SQL SELECT

Beitrag von DeathAndPain (Top Expert / 1947 / 257 / 413 ) »
Tatsächlich habe ich als erstes an den Join gedacht. Subquerys sind mir irgendwie suspekt.

Das hier halte ich für den Sonderfall, bei dem Tabellenaliase tatsächlich was bringen und damit gerechtfertigt sind. Ich hasse die - leider auch von rob_abc in seinem Beispiel praktizierte - Angewohnheit vieler Programmierer, bei allen SELECTs Tabellenaliase zu definieren, wodurch schlechter lesbar wird, welche Tabellen da miteinander verknüpft werden und wo die Ergebniswerte herkommen. Ohne Alias wird der Tabellenname selbst verwendet, und das liest sich deutlich verständlicher.

Hier aber muss bei einem JOIN zweimal dieselbe Tabelle verknüpft werden, und dafür braucht man dann tatsächlich den Alias.

In meiner Naivität würde ich behaupten, dass es so funktioniert (hier ohne Inline-Deklaration der Zieltabelle, damit ich mir die Lesbarkeit nicht mit den ganzen blöden @-Symbolen verschandeln muss):

Code: Alles auswählen.

SELECT t_id~* INTO test FROM g_db as t_farbe
  JOIN g_db as t_id
    ON t_id-id = t_farbe_id
 WHERE t_farbe-farbe IN ('Rot','blau').

Re: SQL SELECT

Beitrag von rob_abc (Specialist / 107 / 27 / 44 ) »
Ich mag Tabellenaliasse auch nicht, aber bei selects auf internen Tabellen wird man von der SAP dazu gezwungen.

Am besten gefällt mir der Inner Join in der Sub-Query. Meine erste Lösung waren die beiden Selects mit dem Group-Loop. Daher auch dieser Thread, um das Konstrukt loszuwerden. Danke für die Hilfe.

Vielleicht gibt es ja eine noch "schönere" Lösung?

@D&P, deinen Lösungsansatz hab ich nicht zu laufen gebracht. Ich bekam immer mehr Datensätze zurück, als die Ausgangstabelle hatte.

Code: Alles auswählen.

REPORT.

CLASS ltc_unit_test DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT.

  PRIVATE SECTION.
    TYPES:
      tty_jest           TYPE SORTED TABLE OF jest WITH UNIQUE KEY objnr stat.

    CLASS-METHODS:
      class_setup.

    METHODS:
      simple_select FOR TESTING,
      subquery_with_inner_join FOR TESTING,
      inner_join FOR TESTING,
      subquery FOR TESTING,
      two_selects FOR TESTING.

    CLASS-DATA:
      g_expected       TYPE tty_jest.

    DATA:
      m_jest           TYPE tty_jest.

ENDCLASS.

CLASS ltc_unit_test IMPLEMENTATION.

  METHOD class_setup.
    DATA(l_test_double) = cl_osql_test_environment=>create(
      VALUE #( ( 'JEST' ) ) ).

    l_test_double->insert_test_data( VALUE jest_tty(
      ( mandt = '100' objnr = 'OR000001000000' stat = 'I0001' )
      ( mandt = '100' objnr = 'OR000001000000' stat = 'I0002' )
      ( mandt = '100' objnr = 'OR000001000000' stat = 'I0003' )
      ( mandt = '100' objnr = 'OR000001000001' stat = 'I0001' )
      ( mandt = '100' objnr = 'OR000001000001' stat = 'I0002' )
      ( mandt = '100' objnr = 'OR000001000001' stat = 'I0004' )
      ( mandt = '100' objnr = 'OR000001000002' stat = 'I0001' )
      ( mandt = '100' objnr = 'OR000001000002' stat = 'I0004' )
      ( mandt = '100' objnr = 'OR000001000002' stat = 'I0005' )
      ( mandt = '100' objnr = 'OR000001000003' stat = 'I0001' )
      ( mandt = '100' objnr = 'OR000001000003' stat = 'I0004' )
      ( mandt = '100' objnr = 'OR000001000003' stat = 'I0006' )
      ( mandt = '100' objnr = 'OR000001000004' stat = 'I0001' ) ) ).

    g_expected = VALUE #(
      ( mandt = '100' objnr = 'OR000001000000' stat = 'I0001' )
      ( mandt = '100' objnr = 'OR000001000000' stat = 'I0002' )
      ( mandt = '100' objnr = 'OR000001000000' stat = 'I0003' )
      ( mandt = '100' objnr = 'OR000001000001' stat = 'I0001' )
      ( mandt = '100' objnr = 'OR000001000001' stat = 'I0002' )
      ( mandt = '100' objnr = 'OR000001000001' stat = 'I0004' ) ).
  ENDMETHOD.

  METHOD simple_select.
    SELECT * FROM jest INTO TABLE @m_jest.
    cl_aunit_assert=>assert_equals( exp = 13 act = lines( m_jest ) ).
  ENDMETHOD.

  METHOD inner_join.
    "???
    "cl_aunit_assert=>assert_equals( exp = g_expected act = m_jest ).
  ENDMETHOD.

  METHOD subquery_with_inner_join.
    SELECT * FROM jest
      WHERE objnr IN (
        SELECT j1~objnr FROM jest AS j1
          INNER JOIN jest AS j2 ON j1~objnr EQ j2~objnr
            WHERE j1~stat EQ 'I0001'
              AND j2~stat EQ 'I0002' )
      INTO TABLE @m_jest.

    cl_aunit_assert=>assert_equals( exp = g_expected act = m_jest ).
  ENDMETHOD.

  METHOD subquery.
    SELECT * FROM jest
      WHERE objnr IN ( SELECT objnr FROM jest WHERE stat = 'I0001' )
        AND objnr IN ( SELECT objnr FROM jest WHERE stat = 'I0002' )
        INTO TABLE @m_jest.

    cl_aunit_assert=>assert_equals( exp = g_expected act = m_jest ).
  ENDMETHOD.

  METHOD two_selects.
    DATA l_object_numbers_for_select TYPE STANDARD TABLE OF jest.
    DATA(l_rng_stat) = VALUE rsdsselopt_t(
      ( sign = 'I' option = 'EQ' low = 'I0001' )
      ( sign = 'I' option = 'EQ' low = 'I0002' ) ).

    SELECT * FROM jest
      WHERE stat IN @l_rng_stat
      ORDER BY PRIMARY KEY
      INTO TABLE @DATA(l_tmp_object_numbers).

    LOOP AT l_tmp_object_numbers ASSIGNING FIELD-SYMBOL(<l>) 
      GROUP BY ( objnr = <l>-objnr size = GROUP SIZE ) 
      REFERENCE INTO DATA(l_group).
      
      IF l_group->size EQ 2.
        INSERT VALUE #( objnr = l_group->objnr ) INTO TABLE l_object_numbers_for_select.
      ENDIF.
    ENDLOOP.

    SELECT * FROM jest
      FOR ALL ENTRIES IN @l_object_numbers_for_select
      WHERE objnr EQ @l_object_numbers_for_select-objnr
      INTO TABLE @m_jest.

    cl_aunit_assert=>assert_equals( exp = g_expected act = m_jest ).
  ENDMETHOD.

ENDCLASS.

Re: SQL SELECT

Beitrag von DeathAndPain (Top Expert / 1947 / 257 / 413 ) »
rob_abc hat geschrieben:
18.05.2023 15:11
Ich mag Tabellenaliasse auch nicht, aber bei selects auf internen Tabellen wird man von der SAP dazu gezwungen.
Ok, die gibt es aber erst ab 7.53, und 7.53 gibt es nicht für SAP HCM, insofern habe ich damit keine Erfahrung.

Wäre für mich aber kein Grund, auch bei Datenbank-SELECTs immer Aliase einzusetzen.
rob_abc hat geschrieben:
18.05.2023 15:11
@D&P, deinen Lösungsansatz hab ich nicht zu laufen gebracht. Ich bekam immer mehr Datensätze zurück, als die Ausgangstabelle hatte.
Wenn ich drüber nachdenke, hast Du recht, und zwar dann, wenn dieselbe ID bei mehreren gewählten Farben (hier also bei rot und bei blau) auftaucht. Nach meinem Dafürhalten dürften das aber nur Duplikate sein, die man mit einem DISTINCT (oder einem FOR ALL ENTRIES IN) wegbekommen können müsste.

Seite 1 von 1

Vergleichbare Themen

8
Antw.
3090
Views
SELECT SINGLE oder SELECT UP TO 1 ROWS?
von nickname8 » 12.04.2021 10:38 • Verfasst in ABAP® für Anfänger
10
Antw.
6709
Views
2 Select-Options zu einem für Select zusammenfügen
von manuk » 23.03.2005 11:02 • Verfasst in ABAP® Core
2
Antw.
2554
Views
Select * und Select von einzelnen Werten zugleich
von StefanJue » 04.10.2006 18:10 • Verfasst in ABAP® für Anfänger
4
Antw.
9356
Views
Performance: SELECT UP TO 1 ROWS vs. SELECT SINGLE
von roman1983 » 04.09.2008 14:29 • Verfasst in ABAP® für Anfänger
2
Antw.
827
Views
Job hängt an select, wie herausfinden welches select
von dpz » 01.08.2019 10:23 • Verfasst in ABAP® Core

Über diesen Beitrag



Unterstütze die Community und teile den Beitrag für mehr Leser und Austausch

Aktuelle Forenbeiträge

Trennen Strasse und Hausnummer
vor 4 Stunden von msfox 18 / 10920
Dialog-Container mit Toolbar/Status
vor 7 Stunden von black_adept gelöst 27 / 4022
IT0024 Qualifikationen CP-ID
vor 9 Stunden von ArjenR 1 / 69

Newsletter Anmeldung

Keine Beiträge verpassen! Wöchentlich versenden wir lesenwerte Beiträge aus unserer Community.
Die letzte Ausgabe findest du hier.
Details zum Versandverfahren und zu Ihren Widerrufsmöglichkeiten findest du in unserer Datenschutzerklärung.

Aktuelle Forenbeiträge

Trennen Strasse und Hausnummer
vor 4 Stunden von msfox 18 / 10920
Dialog-Container mit Toolbar/Status
vor 7 Stunden von black_adept gelöst 27 / 4022
IT0024 Qualifikationen CP-ID
vor 9 Stunden von ArjenR 1 / 69

Unbeantwortete Forenbeiträge

IT0024 Qualifikationen CP-ID
vor 9 Stunden von ArjenR 1 / 69
aRFC im OO-Kontext
vor 4 Wochen von ralf.wenzel 1 / 3003
Hilfe bei SWEC/SWE2
September 2024 von retsch 1 / 9593