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 Ergebniszeilen

    Und 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 auf rp.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 aus

    SELECT @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 ausgeben

    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, 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 das LIKE durch ein = ersetzen. Oder ist LIKE hier irgendwie trotzdem notwendig? Ich hoffe doch dass sPANr keine % enthält die dann als Wildcards beim LIKE verwendet werden müssen.
    (BTW: Wenn sPANr 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 muss pa 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_wa

    4 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 die wa/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' vs rp.nmodulken = 2 stimmt so?
    Kommt mir nur komisch vor dass im "oberen" Teil immer mit 3 verglichen wird, im "unteren" Teil dann bei wa auch mit 3 aber bei we 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. -> WE

    Vielen DAnk nochmal für deine tolle Hilfe und Unterstützung!


Anmelden zum Antworten