SQL Abfrage mit Ergebnissen von vorheriger Abfrage einzeln aufrufen
-
Hallo,
ich habe eine Relativ komplizierte, für mich komplizierte, Abfrage in SQL vor.
(Oracle)Ich habe eine Abfrage, die mir eine Anzahl an Ergebnissen liefert. Die Anzahl ist unterschiedlich. Bei den Ergebnissen handelt es sich um Auftragsnummern die ein Stringformat haben.
z.B:2010201020 2014209021 2010201029 12-XX-1234
Und für jede Zeile der Ergebnisse müsste ich nun eine weitere SQL-Abfrage aufrufen wo dann als Abfrage die Variable &auftragsnr mit der Ergebnisszeile gefüllt wird. Und dann hätte ich das Ergebnis gern gesammelt abgebildet.
SELECT rs.srqnr , rs.sbemeingabe, rs.dtabschluss , rs.szustxt1 , rtz.stxt status, rs.nlfdzusinfo5nr FROM STAMM rs, TEXT rtz WHERE rs.nreklart = rtz.ntxtnr AND rtz.nlgeken = 1 AND rtz.ntxtken = 5 AND rs.srqnr LIKE 'XXX%' AND ( rs.sfeldnr1 LIKE '%". $auftragsnr ."%' OR rs.nlfdpanr = (SELECT nlfdpanr FROM AUFTRAG WHERE spanr LIKE '". $auftragsnr ."') ) UNION ALL SELECT rs.srqnr, rs.sbemeingabe, rp.dtabschluss, rs.szustxt1, s.status, rp.nlfdposnr FROM STAMM rs, POSITION rp, STATUS_POSITION s WHERE rp.nlfdpanr = (SELECT nlfdpanr FROM AUFTRAG WHERE spanr LIKE '". $auftragsnr ."') AND rp.nrqnr = rs.nrqnr AND rp.nfeldnr2 = s.wert and rp.nmodulken=3 UNION ALL SELECT rs.srqnr, rs.sbemeingabe, rp.dtabschluss, rs.szustxt1, s.status, rp.nlfdposnr FROM STAMM rs, POSITION rp, STATUS_POSITION s WHERE rp.nlfdpanr = (SELECT nlfdpanr FROM AUFTRAG WHERE spanr LIKE '". $auftragsnr ."') AND rp.nrqnr = rs.nrqnr AND rp.nfeldnr2 = s.wert and rp.nmodulken=2"
Ist dies möglich?
-
Geht's hier um Geschwindigkeit (viele Zeilen, soll schnell laufen)?
Oder geht's eher darum es so einfach wie möglich zu machen damit es halbwegs wartbar und verständlich bleibt?Falls zweiteres, dann würde ich sagen:
Mach nen Table-Table für die Auftragsnummern
Befüll den Table-Table für die Auftragsnummern
Mach nen Temp-Table für die Ergebniszeilen
Mach nen Cursor auf den Table-Table für die Auftragsnummern auf
Geh' alle Zeilen durch
Pro Auftragsnummer: führ ein INSERT mit der von dir gezeigte Abfrage durch und befülle damit den Temp-Table für die ErgebniszeilenUnd zum Schluss ein SELECT auf den Temp-Table für die Ergebniszeilen
Falls es um Geschwindigkeit geht ... wird es etwas komplizierter
ps:
Die letzten beiden Teil-SELECTs sind bis aufrp.nmodulken=3
vs.rp.nmodulken=2
identisch, oder? Dann solltest du die auch zu einem einzigen SELECT zusammenfassen.
-
Ziel wäre, so einfach wie möglich.
Wunsch wäre es die Abfrage zu formulieren, dass das Ergebnis dann auf einer Website abgebildet wird.Hintergrund:
Es existiert ein Hauptauftrag der sich aus anderen Aufträgen zusammensetzt und diese sind ebenfalls mal aus anderen Aufträgen erstellt worden.
Man frägt also den Hauptauftrag in der ersten Abfrage ab und erhält dann die Liste aller beteiligten Aufträge.
und diese Liste soll denn jeweils auf den Übersandten SQL angewendet werden.Ich hatte auch schon im Sinn die Abfrage mit dem Hauptauftag in die mitgesandte Abfrage einzubauen. Das ganze funktioniert bei den
WHERE rp.nlfdpanr IN (SELECT nlfdpanr FROM AUFTRAG WHERE spanr IN' UNTERABFRAGE')
Jedoch weiß ich nicht wie ich die Like-Abfrage ersetzen müsste, dass Sie für mehere Ergebnisse funktioniert
AND ( rs.sfeldnr1 LIKE '%". $auftragsnr ."%' OR...
-
aLeXanDer.. schrieb:
Ich hatte auch schon im Sinn die Abfrage mit dem Hauptauftag in die mitgesandte Abfrage einzubauen. Das ganze funktioniert bei den
WHERE rp.nlfdpanr IN (SELECT nlfdpanr FROM AUFTRAG WHERE spanr IN' UNTERABFRAGE')
Jedoch weiß ich nicht wie ich die Like-Abfrage ersetzen müsste, dass Sie für mehere Ergebnisse funktioniert
AND ( rs.sfeldnr1 LIKE '%". $auftragsnr ."%' OR...
Mit
LIKE
geht das so direkt gar nicht.Es sollte aber möglich sein das über nen CROSS JOIN zu machen, und dann einfach im WHILE zu filtern.
Also ausSELECT @a = a FROM tab_a WHERE ...; -- ein a holen SELECT * FROM tab_b WHERE b LIKE ('%' || @a || '%') -- b zeilen zu diesem a holen
machst du
SELECT * FROM tab_b CROSS JOIN tab_a WHERE b LIKE ('%' || tab_a.a || '%') AND ... -- alle b zu allen a holen
Siehe
http://stackoverflow.com/questions/3828842/how-to-like-two-columns-in-one-sql-statement
-
ps: Was soll eigentlich diese ganze
LIKE
Scheisse? Das ist ja furchtbares Datenbankdesign. Wer macht denn sowas???
-
dieser Like-Scheiss ist notwendig weil der Softwarehersteller die Aufträge in der DB in ein Textfeld mit Trennzeichen einträgt.... und ohne diesen Like-Scheiss sonst leider nicht alle zugehörigen Einträge zu den Aufträgen angezeigt werden -.- Ich probiere mal deinen Vorschlag umzusetzen. Vielen Dank für die Hilfe schon mal!
-
Bezüglich dem CROSS Join noch eine Frage.
Meine 1. Abfrage wäre diese hier, welche dann X Ergebnisse liefert.
select pa.sPANr from pa_kopf_wa pa where pa.nLfdChargenNr in (select nLfdChargenNrS from chargeref where nLfdChargenNrD in (select nLfdChargenNrS from chargeref where nLfdChargenNrD in (select nLfdChargenNrS from chargeRef where nLfdChargenNrD = (select nLfdChargenNr from charge where sChargenNr = '" . $auftragsnummer . "' and nlfdmodulken ='3') ) ) ) UNION select pa.sPANr from pa_kopf_we pa where pa.nLfdChargenNr in (select nLfdChargenNrS from chargeref where nLfdChargenNrD in (select nLfdChargenNrS from chargeref where nLfdChargenNrD in (select nLfdChargenNrS from chargeRef where nLfdChargenNrD = (select nLfdChargenNr from charge where sChargenNr = '" . $auftragsnummer . "' and nlfdmodulken ='3' ) ) ) ) UNION select pa.sPANr from pa_kopf_we pawhere pa.nLfdChargenNr in (select nLfdChargenNrS from chargeref where nLfdChargenNrD in (select nLfdChargenNrS from chargeRef where nLfdChargenNrD = (select nLfdChargenNr from charge where sChargenNr = '" . $auftragsnummer . "' and nlfdmodulken ='3' ) ) ) UNION select pa.sPANr from pa_kopf_we pa where pa.nLfdChargenNr in (select nLfdChargenNrS from chargeRef where nLfdChargenNrD = (select nLfdChargenNr from charge where sChargenNr = '" . $auftragsnummer . "' and nlfdmodulken ='3' ) ) UNION select pa.sPANr from pa_kopf_wa pa where pa.nLfdChargenNr in (select nLfdChargenNrS from chargeref where nLfdChargenNrD in (select nLfdChargenNrS from chargeRef where nLfdChargenNrD = (select nLfdChargenNr from charge where sChargenNr = '" . $auftragsnummer . "' and nlfdmodulken ='3' ) ) ) UNION select pa.sPANr from pa_kopf_wa pa where pa.nLfdChargenNr in (select nLfdChargenNrS from chargeref where nLfdChargenNrD in (select nLfdChargenNrS from chargeRef where nLfdChargenNrD = (select nLfdChargenNr from charge where sChargenNr = '" . $auftragsnummer . "' and nlfdmodulken ='3' ) ) ) UNION select pa.sPANr from pa_kopf_wa pa where pa.nLfdChargenNr in (select nLfdChargenNrS from chargeRef where nLfdChargenNrD = (select nLfdChargenNr from charge where sChargenNr = '" . $auftragsnummer . "' and nlfdmodulken ='3' ) )
und mit jedem dieser Ergebnisse müsste ich dann den nachfolgenden SQL aufrufen
und dann ein Gesamtergebnis ausgebenSELECT rs.srqnr pam_nr, rs.sbemeingabe reklamationsgrund, rs.dtabschluss abschlussdatum, rs.szustxt1 basis_pam, rtz.stxt status, rs.nlfdzusinfo5nr POSITION FROM rqms_stamm rs, rqms_txt_zuw rtz WHERE rs.nreklart = rtz.ntxtnr AND rtz.nlgeken = 1 AND rtz.ntxtken = 5 AND rs.srqnr LIKE 'PAM%' AND ( rs.sfeldnr1 LIKE '%". $ErgebnisausAbfrage1 ."%' OR rs.nlfdpanr = (SELECT nlfdpanr FROM pa_kopf_wa WHERE spanr LIKE '". $ErgebnisausAbfrage1 ."') ) UNION ALL SELECT rs.srqnr, rs.sbemeingabe, rp.dtabschluss, rs.szustxt1, s.status, rp.nlfdposnr FROM rqms_stamm rs, rqms_pos rp, status_rqms_pos s WHERE rp.nlfdpanr = (SELECT nlfdpanr FROM pa_kopf_wa WHERE spanr LIKE '". $ErgebnisausAbfrage1 ."') AND rp.nrqnr = rs.nrqnr AND rp.nfeldnr2 = s.wert and rp.nmodulken=3 UNION ALL SELECT rs.srqnr, rs.sbemeingabe, rp.dtabschluss, rs.szustxt1, s.status, rp.nlfdposnr FROM rqms_stamm rs, rqms_pos rp, status_rqms_pos s WHERE rp.nlfdpanr = (SELECT nlfdpanr FROM pa_kopf_we WHERE spanr LIKE '". $ErgebnisausAbfrage1 ."') AND rp.nrqnr = rs.nrqnr AND rp.nfeldnr2 = s.wert and rp.nmodulken=2
Funktioniert das über einen CROSS JOIN ?
-
Ist das PHP-String Interpolation? Heisst ... also im Feld sChargenNr steht wirklich
" . XXX . "
drinnen, wobei
XXX
eben die "Chargennummer" ist? Also inklusive Anführungszeichen, Leerzeichen und Punkte?Und beim 2. Teil dann in den Feldern
sfeldnr1
bzw.nlfdpanr
das selbe komische Format, nur zur Abwechslung ohne Leerzeichen zwischen " und .? WTF?Dann könnte man ja bei das
spanr LIKE '". $ErgebnisausAbfrage1 ."'
schonmal dasLIKE
durch ein=
ersetzen. Oder istLIKE
hier irgendwie trotzdem notwendig? Ich hoffe doch dasssPANr
keine%
enthält die dann als Wildcards beimLIKE
verwendet werden müssen.
(BTW: WennsPANr
jemals % enthalten KANN, und sie nicht als Wildcard verwendet werden sollen, dann müsste man diese % escapen!)Die einzigen LIKE die dann übrigbleiben würden wären das mit
'%". $ErgebnisausAbfrage1 ."%'
und das mit'PAM%'
.Korrekt soweit?
Davon abgesehen ... bist du sicher dass die Abfrage so in deinem Programm steht? Weil da nämlich zumindest ein Space fehlt (
pawhere
musspa where
heissen).Weiters... der Teil
select pa.sPANr from pa_kopf_wa pa where pa.nLfdChargenNr in (select nLfdChargenNrS from chargeref where nLfdChargenNrD in (select nLfdChargenNrS from chargeRef where nLfdChargenNrD = (select nLfdChargenNr from charge where sChargenNr = '" . $auftragsnummer . "' and nlfdmodulken ='3' ) ) )
ist doppelt vorhanden, wenn ich nicht wieder 'was übersehen habe. Macht zwar keinen Unterschied, weil UNION und nicht UNION ALL, aber ist trotzdem irgendwie komisch.
Und natürlich ist die ganze Sache ein wenig komisch angeordnet.
`4 Levels tief mit pa_kopf_wa4 Levels tief mit pa_kopf_we
3 Levels tief mit pa_kopf_we
2 Levels tief mit pa_kopf_we
3 Levels tief mit pa_kopf_wa
3 Levels tief mit pa_kopf_wa
2 Levels tief mit pa_kopf_wa`
Ergibt irgendwie kein Muster.
Wenn dann hätte ich erst alle WA dann alle WE erwartet, oder erst alle 4er, dann alle 3er dann alle 2er.Alles a bissi komisch.
-
Ja das ganze ist ein Select der über eine PHP-Seite befüllt wird.
" . $auftragsnummer . " entspricht der Nummer die auf der Seite eingegeben wird
---> ...= '1020301011' where ...Das fehlende Leerzeichen ist mein Fehler beim Kopieren gewesen.
Das mit den Liks durch = ersetzen ist korrekt. das Like ist hier nicht notwendig.Ja die Anordnung ist genau verkehrt rum.
Ist durch das nachträgliche ergänzen so enstanden :-S
-
OK.
Hm.
Probier mal so; WITH wa (sPANr, nlfdpanr) AS ( SELECT pa.sPANr, pa.nlfdpanr FROM pa_kopf_wa pa WHERE pa.nLfdChargenNr IN (SELECT nLfdChargenNrS FROM chargeRef WHERE nLfdChargenNrD = (SELECT nLfdChargenNr FROM charge WHERE sChargenNr = '" . $auftragsnummer . "' and nlfdmodulken ='3' ) ) UNION SELECT pa.sPANr, pa.nlfdpanr FROM pa_kopf_wa pa WHERE pa.nLfdChargenNr IN (SELECT nLfdChargenNrS FROM chargeref WHERE nLfdChargenNrD IN (SELECT nLfdChargenNrS FROM chargeRef WHERE nLfdChargenNrD = (SELECT nLfdChargenNr FROM charge WHERE sChargenNr = '" . $auftragsnummer . "' and nlfdmodulken ='3' ) ) ) UNION SELECT pa.sPANr, pa.nlfdpanr FROM pa_kopf_wa pa WHERE pa.nLfdChargenNr IN (SELECT nLfdChargenNrS FROM chargeref WHERE nLfdChargenNrD IN (SELECT nLfdChargenNrS FROM chargeref WHERE nLfdChargenNrD IN (SELECT nLfdChargenNrS FROM chargeRef WHERE nLfdChargenNrD = (SELECT nLfdChargenNr FROM charge WHERE sChargenNr = '" . $auftragsnummer . "' and nlfdmodulken ='3') ) ) ) ), we (sPANr, nlfdpanr) AS ( SELECT pa.sPANr, pa.nlfdpanr FROM pa_kopf_we pa WHERE pa.nLfdChargenNr IN (SELECT nLfdChargenNrS FROM chargeRef WHERE nLfdChargenNrD = (SELECT nLfdChargenNr FROM charge WHERE sChargenNr = '" . $auftragsnummer . "' and nlfdmodulken ='3' ) ) UNION SELECT pa.sPANr, pa.nlfdpanr FROM pa_kopf_we pa WHERE pa.nLfdChargenNr IN (SELECT nLfdChargenNrS FROM chargeref where nLfdChargenNrD IN (SELECT nLfdChargenNrS FROM chargeRef WHERE nLfdChargenNrD = (SELECT nLfdChargenNr FROM charge WHERE sChargenNr = '" . $auftragsnummer . "' and nlfdmodulken ='3' ) ) ) UNION SELECT pa.sPANr, pa.nlfdpanr FROM pa_kopf_we pa WHERE pa.nLfdChargenNr IN (SELECT nLfdChargenNrS FROM chargeref WHERE nLfdChargenNrD IN (SELECT nLfdChargenNrS FROM chargeref WHERE nLfdChargenNrD IN (SELECT nLfdChargenNrS FROM chargeRef WHERE nLfdChargenNrD = (SELECT nLfdChargenNr FROM charge WHERE sChargenNr = '" . $auftragsnummer . "' and nlfdmodulken ='3' ) ) ) ) ), wx (sPANr) AS ( SELECT sPANr FROM wa UNION SELECT sPANr FROM we ) SELECT rs.srqnr pam_nr, rs.sbemeingabe reklamationsgrund, rs.dtabschluss abschlussdatum, rs.szustxt1 basis_pam, rtz.stxt status, rs.nlfdzusinfo5nr POSITION FROM rqms_stamm rs INNER JOIN rqms_txt_zuw rtz ON rtz.ntxtnr = rs.nreklart AND rtz.nlgeken = 1 AND rtz.ntxtken = 5 CROSS JOIN wx WHERE rs.srqnr LIKE 'PAM%' AND ( rs.sfeldnr1 LIKE '%' || wx.sPANr || '%' OR rs.nlfdpanr = (SELECT nlfdpanr FROM pa_kopf_wa WHERE spanr = wx.sPANr) ) UNION ALL SELECT rs.srqnr, rs.sbemeingabe, rp.dtabschluss, rs.szustxt1, s.status, rp.nlfdposnr FROM wa INNER JOIN rqms_pos rp ON rp.nlfdpanr = wa.nlfdpanr AND rp.nmodulken = 3 INNER JOIN rqms_stamm rs ON rs.nrqnr = rp.nrqnr INNER JOIN status_rqms_pos s ON s.wert = rp.nfeldnr2 UNION ALL SELECT rs.srqnr, rs.sbemeingabe, rp.dtabschluss, rs.szustxt1, s.status, rp.nlfdposnr FROM we INNER JOIN rqms_pos rp ON rp.nlfdpanr = we.nlfdpanr AND rp.nmodulken = 2 INNER JOIN rqms_stamm rs ON rs.nrqnr = rp.nrqnr INNER JOIN status_rqms_pos s ON s.wert = rp.nfeldnr2
Der
OR rs.nlfdpanr = (SELECT nlfdpanr FROM pa_kopf_wa WHERE spanr = wx.sPANr)
Teil ist immer noch komisch. Sieht für mich eher so aus als ob die Abfrage wo der vorkommt auch gesplittet werden sollte, 1x für "we" und 1x für "wa" (was auch immer we und wa bedeuten).
-
Vielen Dank für deine Hilfe, das sieht sehr gut aus!
Hab lediglich die Abfrage dann noch um den eingegebenen FA erweiert.
Bezüglich der Anmerkung zu der OR Abfrage hast du recht.
Das ganze muss man natürlich splitten.Dankeschön
-
Funktioniert es denn? Ich konnte es nicht testen, hab wie gesagt kein Oracle hier.
Wenn es gesplittet gehört, dann hätte es auch im "Original" das du gepostet hast schon gesplittet gehört.
Und wenn du es splittest, dann kann das OR gleich direkt auf die
nlfdpanr
Spalte zugreifen die ich mit in diewa/we
Common Table Expressions aufgenommen habe. Genau so wie ich den sub-SELECT auch in den anderen beiden SELECTs entfernt habe.aLeXanDer.. schrieb:
Hab lediglich die Abfrage dann noch um den eingegebenen FA erweiert.
FA? Bahnhof?
BTW: Das mit
nlfdmodulken = '3'
vsrp.nmodulken = 2
stimmt so?
Kommt mir nur komisch vor dass im "oberen" Teil immer mit 3 verglichen wird, im "unteren" Teil dann beiwa
auch mit 3 aber beiwe
mit 2.
Da ich keine Ahnung habe was die Felder bedeuten kann ich natürlich nicht sicher sagen dass es nicht stimmt. Ich stelle nur fest dass ich hier ein Muster erwartet hätte das sich eben nicht ergibt.
-
Ja funktioniert.
Vielen Dank dafür!Ja hast du recht, im Orginal ist folglich ein Fehler enthalten, weil die Abfrage gefehlt hat.Also vielen Dank für den Hinweis!
Mit FA meinte ich, dass ich die eingegebene Nummer in der Webabfrage ebenfalls zu der "Ergebnismenge" aus der ersten Abfrage mit hinzugefügt habe, dass diese in der 2. Abfrage auch mit betrachtet wird.
das mit der modulken stimmt so. Tabelle we hat modulken 2 und wa modulken 3 und das ist in der rp tabelle dann entspr. hinterlegt.
im oberen teil benutzt man die 3, weil man bestimmt hat, dass die eingegebene nummer eine nummer aus der tabelle wa sein muss.
-
aLeXanDer.. schrieb:
im oberen teil benutzt man die 3, weil man bestimmt hat, dass die eingegebene nummer eine nummer aus der tabelle wa sein muss.
Wieso sucht man dann noch in we?
Versteh' ich nicht so ganz.
Naja, egal. Wenn's funktioniert und du meinst dass das jetzt so richtig ist, dann ist ja alles gut.
-
die Auftragsnummer mit der Gesucht wird ist er Endauftrag -> WA
Dieser ist aus Voraufträgen entstanden und diese ebenfalls usw.
und Iwann wurde das ganze ja mal eingekauft. -> WEVielen DAnk nochmal für deine tolle Hilfe und Unterstützung!