Code: Alles auswählen.
Select imrg~mdocm,
imrg~point,
imrg~mdocm,
imrg~recdv,
imptt~psort,
imptt~pttxt,
imptt~decim
FROM imrg
JOIN imptt on imptt~point = imrg~point
where imrg~woobl = @iv_objnr
into table @data(lt_result).
Code: Alles auswählen.
SELECT imrg~mdocm,
imrg~point,
imrg~recdv,
imptt~psort,
imptt~pttxt,
imptt~decim
FROM imrg
JOIN imptt ON imptt~point = imrg~point
WHERE imrg~woobj = @iv_objnr
AND imrg~erdat = ( SELECT MAX( erdat )
FROM imrg
WHERE woobj = @iv_objnr )
AND imrg~eruhr = ( SELECT MAX( eruhr )
FROM imrg
WHERE woobj = @iv_objnr
AND erdat = ( SELECT MAX( erdat )
FROM imrg
WHERE woobj = @iv_objnr ) )
INTO TABLE @DATA(lt_result).
Code: Alles auswählen.
SORT lt_result DESCENDING BY erdat eruhr.
DATA(ls_result) = lt_result[ 1 ]. " " #91; sowie #93; stehen für eckige Klammern
Reicht für ein einzelnes Ergebnis an dieser Stelle nicht auch einfach ein "SELECT SINGLE..." und eine zugehörige ORDER BY-Anweisung?moo_jo hat geschrieben:Hallo zusammen,
Kann mir bitte jemand einen Tipp für den SQL Join geben.In diesem vereinfachten Beispiel habe ich das Problem, dass der SELECT mir alle MeasurementDocuments zu dem MeasurementPoint zurückgibt. Ich möchte aber nur das aktuelle / neueste Measurement Document.Code: Alles auswählen.
Select imrg~mdocm, imrg~point, imrg~mdocm, imrg~recdv, imptt~psort, imptt~pttxt, imptt~decim FROM imrg JOIN imptt on imptt~point = imrg~point where imrg~woobl = @iv_objnr into table @data(lt_result).
Jetzt hätte ich gehofft den JOIN noch einzugrenzen, aber da stehe ich gerade auf dem Schlauch?
Problem verstanden?
Dankeeeee!
Moo_jo
Folgende Benutzer bedankten sich beim Autor ralf.wenzel für den Beitrag:
tm987456
Öhm, genau das macht doch der SELECT...UP TO 1 ROWS. ENDSELECT.moo_jo hat geschrieben:Ich möchte also jeden Messpunkt genau 1 mal auslesen, wenn er öfters in der Tabelle vorkommt, dann den neuesten. Und das am liebsten in einem SQL Select.
Also die Behauptung halte ich für so absurd, dass ich sie sofort mit einem Testprogramm nachgeprüft und widerlegt habe. Zu diesem Zweck habe ich meine Lieblingstabelle HRP1001 genutzt, die selbst in unserem Entwicklungssystem über 118.000 Einträge hat. Dort habe ich zwei unterschiedliche Einträge (um datenbankseitiges Caching zu vermeiden) per SELECT SINGLE gesucht, zum einen mit dem Primärschlüssel (na ja, einem so langen Teil davon, dass die Suche eindeutig war), zum anderen mit meinen Lieblingsindex 003. Dazu muss man sagen, dass beide Indizes geeignet sind, Tabellenzeilen zu finden. Der wesentliche Vorteil meines Lieblingsindexs besteht nur darin, dass fachliches Wissen über die Tabelle genutzt wird, um mit Angabe von weniger Spalten gleichfalls die gesuchte Zeile treffend zu beschreiben, was in einer kürzeren WHERE-Bedingung resultiert. Zudem kann man mutmaßen, dass es auch datenbankseitig ein kleines bisschen mehr Performance bringt, wenn er weniger Spalten vergleichen muss.Ralf hat geschrieben:Ein SELECT SINGLE mit anderen WHERE Kriterien als dem Primärschlüssel kann unter Umständen eine sequentielle Suche zur Folge haben, die entsprechend lange dauert.
...
Es geht nicht um Sicherheit beim besten passenden Schlüssel, sondern (ich wiederhole mich) um die Kosten des DB-Zugriffs. Ein falscher Schlüssel kann da fatale Folgen haben.
Code: Alles auswählen.
*&---------------------------------------------------------------------*
*& Report ZTEST6
*&---------------------------------------------------------------------*
REPORT ZTEST6.
TABLES HRP1001.
DATA: T1 TYPE I, T2 TYPE I, T3 TYPE I.
PARAMETERS ERSTEINS RADIOBUTTON GROUP ONE.
PARAMETERS ERSTZWEI RADIOBUTTON GROUP ONE.
*** START-OF-SELECTION ***
START-OF-SELECTION.
CASE ERSTEINS.
WHEN 'X'. PERFORM EINS.
PERFORM ZWEI.
WHEN SPACE. PERFORM ZWEI.
PERFORM EINS.
ENDCASE.
*&---------------------------------------------------------------------*
*& Form EINS
*&---------------------------------------------------------------------*
FORM EINS.
GET RUN TIME FIELD T1.
SELECT SINGLE * FROM HRP1001
WHERE SOBID = '50059823'
AND SCLAS = 'S'
AND SUBTY = 'B008'
AND PLVAR = '01'
AND ENDDA = '99991231'
AND BEGDA <= SY-DATUM.
GET RUN TIME FIELD T2.
T3 = T2 - T1.
WRITE / T3.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form ZWEI
*&---------------------------------------------------------------------*
FORM ZWEI.
GET RUN TIME FIELD T1.
SELECT SINGLE * FROM HRP1001
WHERE OTYPE = 'S'
AND OBJID = '50059823'
AND PLVAR = '01'
AND RSIGN = 'A'
AND RELAT = '008'
AND ISTAT = '1'
AND PRIOX = SPACE
AND BEGDA <= SY-DATUM
AND ENDDA = '99991231'.
GET RUN TIME FIELD T2.
T3 = T2 - T1.
WRITE / T3.
ENDFORM.
Eine SELECT-Anweisung mit dem Zusatz SINGLE ist bei vollständig spezifizierter Zeile in aller Regel schneller als bei unvollständiger Spezifizierung der Zeile.
Was, glaubst du, tut eine DB, wenn du in der WHERE-Bedingung irgendein Nicht-Schlüsselfeld mitgibst (und kein Schlüsselfeld)? Sie wird nichts anderes tun können, als die DB zu durchsuchen, und zwar sequentiell. Ich kenne die Tabelle nicht, mit der du gearbeitet hast und ich habe jetzt keine Zeit, das nachzuvollziehen (ich packe gleich für eine Geschäftsreise), aber diese Logik sollte sich dir doch erschließen, oder?Es wird empfohlen, den Zusatz UP TO 1 ROWS zu verwenden, um maximal eine Zeile einer Menge von selektierten zu lesen
Bei der Angabe von SINGLE sollte die zu lesende Zeile aus Effizienzgründen eindeutig in der WHERE-Bedingung spezifiziert sein. Beim Lesen aus einer Datenbanktabelle geschieht dies durch die Angabe von Vergleichswerten für den Primärschlüssel.
Nein. Es ist jedesmal ein Index beteiligt, aber in einem der beiden Fälle ist es eben nicht der Primärindex. Und genau das ist es, was Ralf hier vehement betont: dass SELECT SINGLE ausschließlich den Primärindex nutzen würde und es daher ein fataler Fehler sei, einen SELECT SINGLE zu nutzen, wenn man einen anderen Index als den Primärschlüssel angibt.Du testest in deinem Programm zweimal den SELECT SINGLE und jedes Mal ist ein (Primär-)Index beteiligt.