none
Verschachtelte Abfragen RRS feed

  • Frage

  • Hallo liebes Forum :)

    Ich hoffe, ich bin im richtigen Unterforum, ansonsten entschuldige ich mich schonmal für die Umstände :)

    Ich wurde auf Arbeit gefragt, ob ich nicht ein paar SQL-Abfragen erstellen könnte, die die Arbeit erleichtern würden. Da ich der einzige in der Firma mit SQL-Kenntnissen bin, hab ich natürlich zugestimmt und mir nichts weiter dabei gedacht. Wie schwer können schon ein paar Abfragen sein ;)

    Als Randinfo, es handelt es sich um ein Vermessungsbüro und die Abfragen sollen in die Software GeoBüro eingebunden werden. Der Server ist ein Microsoft 2008 R2 Server.

    Es gibt Unmengen an Tabellen, in die ich mich erstmal reinfinden musste. Beispielsweise gibt es eine Tabelle für die Aufträge, dann gibt es eine Tabelle für die verschiedenen Vorgänge in diesen Aufträgen und wieder diverse andere Tabellen für Auftragsarten und so weiter. Alles ziemlich weitflächig aufgeteilt und verknüpft.

    Das macht dann Abfragen nicht sonderlich leicht, wenn man mehrere Kriterien betrachten muss. Meine SQL-Kenntnisse sind auch etwas eingerostet und ich hatte mich schonmal an Subquerys probiert, aber das funktionierte auch nicht so, wie gedacht.

    Ich werf dann einfach mal eine der gewünschten Abfragen in den Raum, vielleicht ist es ja gar nicht so kompliziert und ich stell mich nur blöd an ;)

    Die Aufgabenstellung:

    "Alle Aufträge, bei denen die Vermessungsunterlagen da sind, aber noch keine Messung im AD (Außendienst) stattgefunden hat
    = Endedatum beim Vorgang "Vermessungsunterlagen sind bestellt" (AVU0), aber kein Vorgang "Messung im AD" (ADB)
    -> Vorgang "Messung im AD" muss konsequent gesetzt werden"

    Aus diesem "Auftrag" hab ich erstmal folgenden Code erstellt:

    SELECT		GBAuftrag.Nummer AS Auftragsnummer, GBAuftrag.Objekt, GBAuftrag.Lage, GBAuftragsart.Name AS Auftragsart, GBAuftrag.Betreff, GBVorgangsart.Kurzname, 
    		GBVorgangsart.Name AS Vorgangsart, GBVorgang.Ende
    
    FROM		GBAuftrag INNER JOIN
    			GBAuftragsart ON GBAuftrag.[#Auftragsart] = GBAuftragsart.ID INNER JOIN
                	GBVorgang ON GBAuftrag.ID = GBVorgang.[#Auftrag] INNER JOIN
                	GBVorgangsart ON GBVorgang.[#Vorgangsart] = GBVorgangsart.ID
    
    WHERE		DATEDIFF(day, GBVorgang.Datum, CURRENT_TIMESTAMP)<=730
    			AND GBVorgang.Ende IS NOT NULL 
    			AND GBVorgangsart.Kurzname = 'AVU0' 
    			AND GBVorgangsart.Kurzname != 'ADB'
    
    ORDER BY	GBAuftrag.Nummer;

    Nun ist es aber der Fall, dass die Kurzbezeichnungen für die Vorgänge ja in der gleichen Spalte der Tabelle liegen, also gibt er mir in der derzeitigen Lage nur die Daten aus, die vorhanden sind, aber zeigt mir nicht an, wo noch der Außendienst fehlt. Hier steh ich irgendwie auf dem Schlauch, wie man das kombinieren könnte und wäre über ein paar andere Ansichten oder Lösungsansätze sehr dankbar, denn die folgenden "Wünsche" der Kollegen werden nicht leichter von der Fomulierung :D

    Dann danke ich Euch schonmal für eure Zeit und eure Ideen.

    LG, Ithron86 :)

    Donnerstag, 20. Juni 2013 06:03

Antworten

  • Habe jetzt von anderer Stelle erstmal eine Lösung bekommen, die auf die ersten Stichproben zu funktionieren scheint. Ich danke euch trotzdem für eure Zeit und Mühe.

    Die Lösung sieht wie folgt aus:

    SELECT		GBAuftrag.Nummer AS Auftragsnummer, GBAuftrag.Objekt, GBAuftrag.Lage, GBAuftragsart.Name AS Auftragsart, GBAuftrag.Betreff, va1.Kurzname, 
    		va1.Name AS Vorgangsart, v1.Ende
    
    FROM    GBAuftrag
    INNER JOIN GBAuftragsart ON GBAuftrag.[#Auftragsart] = GBAuftragsart.ID
    INNER JOIN GBVorgang v1 ON GBAuftrag.ID = v1.[#Auftrag]
    INNER JOIN GBVorgangsart va1 ON v1.[#Vorgangsart] = va1.ID
    WHERE		DATEDIFF(day, v1.Datum, CURRENT_TIMESTAMP)<=730
    			AND        v1.Ende IS NOT NULL
    AND        va1.Kurzname = 'AVU0'
    AND NOT EXISTS (    SELECT    1
                        FROM    GBVorgang v2
                        INNER JOIN GBVorgangsart va2 ON v2.[#Vorgangsart] = va2.ID
                        WHERE    GBAuftrag.ID = v2.[#Auftrag]
                        AND        va2.Kurzname = 'ADB' )
    
    ORDER BY	GBAuftrag.Nummer;

    Die doppelte Betrachtung der Tabelle war scheinbar der Knackpunkt, den ich nicht gemerkt habe :)

    • Als Antwort markiert Ithron86 Donnerstag, 20. Juni 2013 07:37
    Donnerstag, 20. Juni 2013 07:37

Alle Antworten

  • Hallo Ithron86,

    Deine Beschreibung ist für mich nicht wirklich erhellend. Es würde mir weiterhelfen, wenn Du einmal beispielhaft postest, welche DS sich in den 4 Tabellen befinden und wie das Ergabnis der Abfrage aussehen soll.

    Gruss Uli

    Donnerstag, 20. Juni 2013 06:22
  • Hallo!

    Ändere mal den INNER JOIN für die Tabelle GBVorgangsart in einen LEFT JOIN.

    Dann sollte es schon ungefähr in die Richtung gehen.

    In der WHERE-Bedingung ist die Abfrage auf != wohl auch nicht korrekt. Hier wäre wohl eher ein 

    NOT EXISTS(Select * from GBVORGANGSART G

    where G.KURZNAME = 'ADB'

    and G. ID = GBVorgang.[#Vorgangsart])

    einzusetzen.


    Einen schoenen Tag noch, Christoph -- Microsoft SQL Server MVP http://www.insidesql.org/blogs/cmu

    Donnerstag, 20. Juni 2013 06:42
  • Hallo Uli,

    das Problem ist, dass die wirklich umfangreich angelegt sind. Ich hab mal die einzelnen Spalten fotografiert und hochgeladen

    ->edit: Links entfernt, da beantwortet und nicht weiter relevant

    Ich hoffe, das hilft etwas weiter. Als Ergebnis würde es mir reichen, wenn ich die Aufträge angezeigt bekomme, wo der Vorgangsartkurzname "AVU0" vorhanden ist mit einem Endedatum aus der Vorgangstabelle (die sind sicher über die Schlüssel verknüpft, aber das übersteigt derzeit meine Fähigkeiten das zu nutzen) und noch keine Vorgangsart "ADB" vorhanden ist.

    Also die ganzen anderen Spalten sind dann nur Zusatz. Select GBAuftrag.Nummer reicht für den Anfang auch, den Rest hatte ich nur zur Überprüfung der Vorgangsarten und Endedatum noch mit rein genommen ;)

    Mein Dilemma ist derzeit, dass er mir nur ausgibt, wo das Endedatum bei AVU0 gesetzt ist, da ich ihm ja sage, dass ADB nicht gesucht wird. Aber das betrifft dann nur die Anzeige der Ergebnisse und nicht den gesuchten Auftrag ansich. Ich hoffe, ich drücke mich nicht zu umständlich aus, ist schon paar Jahre her, dass wir das im Studium hatten ;)


    • Bearbeitet Ithron86 Donnerstag, 20. Juni 2013 08:04 Bildlinkentfernung nach Beantwortung
    Donnerstag, 20. Juni 2013 06:53
  • Hallo Christoph,

    Danke für deinen Vorschlag, aber er gibt mir immernoch Aufträge aus, wo der Vorgang ADB bereits gesetzt und beendet ist.

    Ist gar nicht so leicht sich nach all den Jahren da wieder reinzufinden, wenn man nur die Grundlagen kennt ;)

    Vielleicht kann man die Schlüssel bei den Vorgängen irgendwie miteinander verbinden, damit er erstmal die Aufträge sucht, wo ein Vorgang vorhanden ist und der andere noch fehlt und dann weiter probieren das Endedatum noch abzufragen.

    Donnerstag, 20. Juni 2013 07:02
  • Habe jetzt von anderer Stelle erstmal eine Lösung bekommen, die auf die ersten Stichproben zu funktionieren scheint. Ich danke euch trotzdem für eure Zeit und Mühe.

    Die Lösung sieht wie folgt aus:

    SELECT		GBAuftrag.Nummer AS Auftragsnummer, GBAuftrag.Objekt, GBAuftrag.Lage, GBAuftragsart.Name AS Auftragsart, GBAuftrag.Betreff, va1.Kurzname, 
    		va1.Name AS Vorgangsart, v1.Ende
    
    FROM    GBAuftrag
    INNER JOIN GBAuftragsart ON GBAuftrag.[#Auftragsart] = GBAuftragsart.ID
    INNER JOIN GBVorgang v1 ON GBAuftrag.ID = v1.[#Auftrag]
    INNER JOIN GBVorgangsart va1 ON v1.[#Vorgangsart] = va1.ID
    WHERE		DATEDIFF(day, v1.Datum, CURRENT_TIMESTAMP)<=730
    			AND        v1.Ende IS NOT NULL
    AND        va1.Kurzname = 'AVU0'
    AND NOT EXISTS (    SELECT    1
                        FROM    GBVorgang v2
                        INNER JOIN GBVorgangsart va2 ON v2.[#Vorgangsart] = va2.ID
                        WHERE    GBAuftrag.ID = v2.[#Auftrag]
                        AND        va2.Kurzname = 'ADB' )
    
    ORDER BY	GBAuftrag.Nummer;

    Die doppelte Betrachtung der Tabelle war scheinbar der Knackpunkt, den ich nicht gemerkt habe :)

    • Als Antwort markiert Ithron86 Donnerstag, 20. Juni 2013 07:37
    Donnerstag, 20. Juni 2013 07:37