Zu den Aufzeichnungen der tutorials.de-Live-Workshops
Like Tree1Danke
  • 1 Beitrag von Yaslaw
ERLEDIGT
NEIN
ANTWORTEN
9
ZUGRIFFE
232
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    AlexD1979 AlexD1979 ist offline Mitglied Gold
    Registriert seit
    Feb 2003
    Ort
    Hannover
    Beiträge
    208
    Hallo,
    Ich denke das ist nicht ganz so easy und ich habe nun schon viel hin- und hergejoint, aber nie das richtige Ergebnis bekommen.
    Ich habe eine Tabelle projekt mit Spalten project_id, project_name,... und eine Tabelle project_milestone mit den Spalten project_id, milestone_id,milestone_date

    Nun brauche ich eine Abfrage, die mir im Result den letzten, gefüllten Meilenstein UND den nächsten leeren Meilenstein liefert.
    Die Tabelle Meilenstein wird bei Neuanlage eines Projekt initial befüllt, d.h. es sind zu bEginn alle Meilensteine bereits in der Tabelle, aber mit leeren milestone_date Feldern.
    project_milestone:
    project_id | milestone_id | milestone_date
    1 | 0 | 2010-05-19 00:00:00
    1 | 1 | 2010-05-20 00:00:00
    1 | 2 | NULL
    1 | 3 | NULL
    1 | 4 | NULL


    Ich bräuchte also sowas in der Art wie
    SELECT
    p.project_id, p.project_name,
    current_milestone = (SELECT ? FROM project_milestone WHERE ?), -- müsste dann 1 ergeben
    next_milestone = (SELECT ? FROM project_milestone WHERE ?) -- müsste dann 2 ergeben
    FROM project p
     

  2. #2
    Avatar von vandamp
    vandamp vandamp ist offline Mitglied Gold
    Registriert seit
    Nov 2003
    Ort
    Wien
    Beiträge
    155
    Hallo,

    ist zwar nicht schön aber sollte das Ergebniss liefern.

    Code sql:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    SELECT
    p.projekt_id,
    p.projekt_name,
    MAX(CASE WHEN pm.milestone_date IS NULL THEN 0 ELSE pm.mildestone_id END) AS current_milestone,
    MIN(CASE WHEN pm.mildestone_date IS NULL THEN pm.milestone_id ELSE 0 END) AS next_milestone
    FROM projekt p , projekt_milestone pm
    WHERE
    pm.projekt_id = p.projekt_id
    GROUP BY
    p.projekt_id,
    p.projekt_name
     
    m.f.g
    b. zimmel

  3. #3
    Avatar von Yaslaw
    Yaslaw Yaslaw ist offline n/a
    tutorials.de Moderator
    Registriert seit
    Dec 2007
    Ort
    Winterthur(CH)
    Beiträge
    4.640
    Unter der Annahme, dass die milestone_id die Meilenstein-Reihenfolge abbildet, kann die 2 gesuchten Werte wie folgt ermitteln:

    id der letzten Meilensteine aller Projekte
    Code sql:
    1
    2
    3
    4
    
    SELECT MAX(milestone_id) AS current_milestone
    FROM project_milestone
    WHERE NOT IS_NULL(milestone_date)
    GROUP BY project_id

    id der nächsten Meilensteine aller Projekte
    Code sql:
    1
    2
    3
    4
    
    SELECT MIN(milestone_id) AS next_milestone
    FROM project_milestone
    WHERE IS_NULL(milestone_date)
    GROUP BY project_id

    Kombiniert sieht es dann etwa so aus (Achtung, ist nicht getestet!)
    Code sql:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
    SELECT
        p.project_id, 
        p.project_name, 
        CURRENT.current_milestone,
        NEXT.next_milestone
    FROM
        project p
        LEFT JOIN ( SELECT MAX(milestone_id) AS current_milestone
                    FROM project_milestone
                    WHERE NOT IS_NULL(milestone_date)
                    GROUP BY project_id) CURRENT
            ON p.project_id = CURRENT.project_id
        LEFT JOIN ( SELECT MIN(milestone_id) AS next_milestone
                    FROM project_milestone
                    WHERE IS_NULL(milestone_date)
                    GROUP BY project_id) NEXT
            ON p.project_id = NEXT.project_id

    Dein Ansatz würde ich nicht machen, da er sonst für jedes Projekt 2 Queries ausführen muss, was nicht gerade performant ist.
     
    ---------------------------------------------------------------------------------------------------
    item: Tutorial: [PHP][MySQL] Debug Queries
    item: Schreibt mir keine PN mit Fragen die im Forum beantwortet werden können - ich mache kein persönliches coaching
    item: Ich habe es mir aus gesundheitlichen Gründen abgewöhnt unformatierten Code zu lesen (Auch SQL-Statements kann man formatieren!)
    item: Bitte zur besseren Lesbarkeit PHP-Code in [PHP]...[/PHP], SQL in [SQL]...[/SQL], Visual Basic in [VB]...[/VB] etc. schreiben

  4. #4
    Avatar von vandamp
    vandamp vandamp ist offline Mitglied Gold
    Registriert seit
    Nov 2003
    Ort
    Wien
    Beiträge
    155
    hmm wenn ich es richtig sehe, machen unsere querrys das selbe, aber warum müsste meiner 2 mal ausgeführt werden?
    Ich hab nur die where clausel in einem case aufgelöst.
     
    m.f.g
    b. zimmel

  5. #5
    Avatar von Yaslaw
    Yaslaw Yaslaw ist offline n/a
    tutorials.de Moderator
    Registriert seit
    Dec 2007
    Ort
    Winterthur(CH)
    Beiträge
    4.640
    Mir ist der Ansatz mit dem Case grad nicht in den Sinn gekommen *g*
     
    ---------------------------------------------------------------------------------------------------
    item: Tutorial: [PHP][MySQL] Debug Queries
    item: Schreibt mir keine PN mit Fragen die im Forum beantwortet werden können - ich mache kein persönliches coaching
    item: Ich habe es mir aus gesundheitlichen Gründen abgewöhnt unformatierten Code zu lesen (Auch SQL-Statements kann man formatieren!)
    item: Bitte zur besseren Lesbarkeit PHP-Code in [PHP]...[/PHP], SQL in [SQL]...[/SQL], Visual Basic in [VB]...[/VB] etc. schreiben

  6. #6
    Avatar von Yaslaw
    Yaslaw Yaslaw ist offline n/a
    tutorials.de Moderator
    Registriert seit
    Dec 2007
    Ort
    Winterthur(CH)
    Beiträge
    4.640
    Hm.. Schlanker als 'Case when then end' gehts mit dem IF(). Dieser intepretiert NULL auch gleich als false.
    Zudem darfst du beim MIN() nicht in CASE 0 zurückgeben, da sonst = als kleinste ID genommen wird. Wir können aber NULL nehmen, da NULL beim MIN ignoriert wird
    Code sql:
    1
    2
    
    MAX(IF(pm.milestone_date, pm.mildestone_id, NULL)) AS current_milestone,
    MIN(IF(pm.milestone_date, NULL, pm.mildestone_id)) AS next_milestone
    vandamp bedankt sich. 
    ---------------------------------------------------------------------------------------------------
    item: Tutorial: [PHP][MySQL] Debug Queries
    item: Schreibt mir keine PN mit Fragen die im Forum beantwortet werden können - ich mache kein persönliches coaching
    item: Ich habe es mir aus gesundheitlichen Gründen abgewöhnt unformatierten Code zu lesen (Auch SQL-Statements kann man formatieren!)
    item: Bitte zur besseren Lesbarkeit PHP-Code in [PHP]...[/PHP], SQL in [SQL]...[/SQL], Visual Basic in [VB]...[/VB] etc. schreiben

  7. #7
    AlexD1979 AlexD1979 ist offline Mitglied Gold
    Registriert seit
    Feb 2003
    Ort
    Hannover
    Beiträge
    208
    Danke für die Tipps, ich werde das mal versuchen.. ich vergaß zu erwähnen dass es sich um einen SQL Server handelt.. die Syntax ist da etwas anders, aber die Denkanstösse von euch helfen schon mal weiter.!!

    Zitat Zitat von yaslaw Beitrag anzeigen
    Unter der Annahme, dass die milestone_id die Meilenstein-Reihenfolge abbildet, kann die 2 gesuchten Werte wie folgt ermitteln:

    id der letzten Meilensteine aller Projekte
    Code sql:
    1
    2
    3
    4
    
    SELECT MAX(milestone_id) AS current_milestone
    FROM project_milestone
    WHERE NOT IS_NULL(milestone_date)
    GROUP BY project_id

    id der nächsten Meilensteine aller Projekte
    Code sql:
    1
    2
    3
    4
    
    SELECT MIN(milestone_id) AS next_milestone
    FROM project_milestone
    WHERE IS_NULL(milestone_date)
    GROUP BY project_id

    Kombiniert sieht es dann etwa so aus (Achtung, ist nicht getestet!)
    Code sql:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
    SELECT
        p.project_id, 
        p.project_name, 
        CURRENT.current_milestone,
        NEXT.next_milestone
    FROM
        project p
        LEFT JOIN ( SELECT MAX(milestone_id) AS current_milestone
                    FROM project_milestone
                    WHERE NOT IS_NULL(milestone_date)
                    GROUP BY project_id) CURRENT
            ON p.project_id = CURRENT.project_id
        LEFT JOIN ( SELECT MIN(milestone_id) AS next_milestone
                    FROM project_milestone
                    WHERE IS_NULL(milestone_date)
                    GROUP BY project_id) NEXT
            ON p.project_id = NEXT.project_id

    Dein Ansatz würde ich nicht machen, da er sonst für jedes Projekt 2 Queries ausführen muss, was nicht gerade performant ist.
     

  8. #8
    Avatar von Yaslaw
    Yaslaw Yaslaw ist offline n/a
    tutorials.de Moderator
    Registriert seit
    Dec 2007
    Ort
    Winterthur(CH)
    Beiträge
    4.640
    Was für ein SQL Server? MS SQL? Oracle?
     
    ---------------------------------------------------------------------------------------------------
    item: Tutorial: [PHP][MySQL] Debug Queries
    item: Schreibt mir keine PN mit Fragen die im Forum beantwortet werden können - ich mache kein persönliches coaching
    item: Ich habe es mir aus gesundheitlichen Gründen abgewöhnt unformatierten Code zu lesen (Auch SQL-Statements kann man formatieren!)
    item: Bitte zur besseren Lesbarkeit PHP-Code in [PHP]...[/PHP], SQL in [SQL]...[/SQL], Visual Basic in [VB]...[/VB] etc. schreiben

  9. #9
    AlexD1979 AlexD1979 ist offline Mitglied Gold
    Registriert seit
    Feb 2003
    Ort
    Hannover
    Beiträge
    208
    Zitat Zitat von yaslaw Beitrag anzeigen
    Was für ein SQL Server? MS SQL? Oracle?
    Hallo MS SQL 2005
    Das mit dem group_by ist für das Beispiel praktikabel, ich habe aber in der finalen Query über 40 Felder in dem Select, die müsste ich dann ja alle in das group_by einhacken oder?
    Das mit dem JOIN geht in SQL SERVER nicht so..
    Code :
    1
    2
    3
    4
    5
    6
    
    select p.project_id,p.inno_ge_project_name,
    max(case when imr.inno_mr_decision_date IS NULL then 0 else imr.milestone_id end) AS passed_milestone,
    min(case when imr.inno_mr_decision_date IS NULL then imr.milestone_id else 0 end) AS next_milestone
    from innovation_project p, innovation_milestone_review imr
    WHERE p.project_id = 15
    GROUP BY p.project_id,p.inno_ge_project_name
    Liefert mir
    15 TEST3 0 0
    wenn noch keiner der Milestones gefüllt ist.. in dem Fall müsste passed leer sein und next milestone = 0
     

  10. #10
    Avatar von Yaslaw
    Yaslaw Yaslaw ist offline n/a
    tutorials.de Moderator
    Registriert seit
    Dec 2007
    Ort
    Winterthur(CH)
    Beiträge
    4.640
    Zitat Zitat von AlexD1979 Beitrag anzeigen
    Hallo MS SQL 2005
    Das mit dem group_by ist für das Beispiel praktikabel, ich habe aber in der finalen Query über 40 Felder in dem Select, die müsste ich dann ja alle in das group_by einhacken oder?
    Nicht unbedingt.
    Man kann auch mit einem JOIN (keine Ahnung wie der im MS SQL geht) nachträglich die Felder dazunehmen

    Beispiel für den current_milestone
    Code sql:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    SELECT
        p.*
    FROM
        project_milestone p,
        (   SELECT MAX(milestone_id) AS current_milestone
                    FROM project_milestone
                    WHERE NOT IS_NULL(milestone_date)
                    GROUP BY project_id) CURRENT
    WHERE
        p.project_id =  CURRENT.current_milestone

    In meinem JOIN hatte ich noch ein Fehler. Bei der Quelle current, muss natürlich nicht auf projekt_id zugegriffen werden, sondern auf current_milestone
    Code sql:
    1
    
            ON p.project_id = CURRENT.current_milestone
    dito natürlich beim next
     
    ---------------------------------------------------------------------------------------------------
    item: Tutorial: [PHP][MySQL] Debug Queries
    item: Schreibt mir keine PN mit Fragen die im Forum beantwortet werden können - ich mache kein persönliches coaching
    item: Ich habe es mir aus gesundheitlichen Gründen abgewöhnt unformatierten Code zu lesen (Auch SQL-Statements kann man formatieren!)
    item: Bitte zur besseren Lesbarkeit PHP-Code in [PHP]...[/PHP], SQL in [SQL]...[/SQL], Visual Basic in [VB]...[/VB] etc. schreiben

Ähnliche Themen

  1. Antworten: 6
    Letzter Beitrag: 25.10.10, 15:40
  2. Join-Abfrage um eine Bedingung hinzufügen
    Von Coldstorm im Forum Relationale Datenbanksysteme
    Antworten: 11
    Letzter Beitrag: 11.07.09, 12:01
  3. (Oracle 10.2) Wertes auf Basis eine min/max Wertes eines anderen Feldes
    Von Sabine_81 im Forum Relationale Datenbanksysteme
    Antworten: 6
    Letzter Beitrag: 27.10.08, 15:49
  4. Eigene Klasse für Abfrage eines XML-Wertes
    Von DanielBodensee im Forum .NET Café
    Antworten: 2
    Letzter Beitrag: 22.07.08, 16:49
  5. Aus einer Abfrage eine Tabelle erstellen
    Von texcamel im Forum Relationale Datenbanksysteme
    Antworten: 1
    Letzter Beitrag: 11.08.04, 23:11