Announcement

Collapse
No announcement yet.

Update über einen Join

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Update über einen Join

    Hi Leute,

    ich bin relativ neu im Thema Datenbanken!
    Ich habe eine DB "modules" gegeben, dass z.B. aus drei Tabellen m1,m2,m3 (Namen sind egal!) besteht und diese haben die gleiche Struktur:

    TaskCommonDim|Resource|TaskStart|TaskEnd|Piority|TaskProcessed
    (ist leider so gegeben!)
    Ich joine per SQL die Tabellen:

    Code:
    SELECT m1.TaskCommonDim, m1.TaskStart, m1.TaskProcessed, m2.TaskStart, m2.TaskProcessed, m3.TaskStart, m2.TaskProcessed
    FROM m1 AS m1
    JOIN m2 AS m2 ON ( m1.TaskCommonDim = m2.TaskCommonDim )
    JOIN m3 AS m3 ON ( m1.TaskCommonDim = m3.TaskCommonDim )
    WHERE m1.TaskProcessed = '0' AND m2.TaskProcessed = '0' AND m3.TaskProcessed = '0'
    TaskStart ist vom Typ Datetime und
    "TaskProcessed" vom Typ int(1), d.h. es kann 0 oder 1 sein

    Nun wollte ich die geringste Datetime aus "TaskStart" (aus der gejointen Tabelle)

    Code:
    UPDATE m1 SET TaskProcessed=true WHERE TaskStart=(SELECT min(TaskStart) FROM m1 );
    Wie kann ich meine Join-Anfrage mit der obigen Update-Anfrage kombinieren? Ich möchte praktisch die kleinste Startzeit aus allen Tabellen und dann "TaskProcessed" in der entsprechenden Zeile der gejointen Tabelle auf 1 setzen!

  • #2
    Geht meine Idee nicht? Ist es mumpitz?

    Comment


    • #3
      Wenn die alle 3 dieselbe Struktur haben, dann brauchst Du sie nicht joinen, sondern kannst sie erstmal per UNION ALL in eine Tabelle zusammenfassen:

      [highlight=sql]
      UPDATE m1 SET TaskProcessed = true WHERE TaskStart =
      (
      SELECT min(TaskStart)
      FROM
      (
      SELECT * FROM m1
      UNION ALL
      SELECT * FROM m2
      UNION ALL
      SELECT * FROM m3
      )
      WHERE taskstart = 0
      )

      UPDATE m2 SET TaskProcessed = true WHERE TaskStart =
      (
      SELECT min(TaskStart)
      FROM
      (
      SELECT * FROM m1
      UNION ALL
      SELECT * FROM m2
      UNION ALL
      SELECT * FROM m3
      )
      WHERE taskstart = 0
      )

      UPDATE m3 SET TaskProcessed = true WHERE TaskStart =
      (
      SELECT min(TaskStart)
      FROM
      (
      SELECT * FROM m1
      UNION ALL
      SELECT * FROM m2
      UNION ALL
      SELECT * FROM m3
      )
      WHERE taskstart = 0
      )
      [/highlight]

      Es wird nur geupdatet, wenn das Datum in der Tabelle auch vorkommt. Allerdings werden auch 2 Datensätze geupdatet, wenn ein identisches Datum drin steht.

      Nicht der schönste Ansatz, aber es würde funktionieren.

      Weitere Sachen die man testen könnte:

      In Oracle gibt es tabellen die nur während der Abfrage existieren. Sieht dann so aus:

      [highlight=sql]
      with taskmin as
      (
      SELECT min(TaskStart) as taskstart
      FROM
      (
      SELECT * FROM m1
      UNION ALL
      SELECT * FROM m2
      UNION ALL
      SELECT * FROM m3
      )
      WHERE taskstart = 0
      )
      UPDATE m1 SET TaskProcessed = true WHERE TaskStart = taskmin.taskstart
      UPDATE m2 SET TaskProcessed = true WHERE TaskStart = taskmin.taskstart
      UPDATE m3 SET TaskProcessed = true WHERE TaskStart = taskmin.taskstart
      [/highlight]

      Ich weiss nicht ob MySQL auch so etwas in der Richtung hat.

      Ich kann mir nicht vorstellen, dass man alles in eine SQL Anweisung packen kann.
      Zuletzt editiert von fanderlf; 08.09.2009, 22:34.

      Comment


      • #4
        Vielen Dank für deine Hilfe! Ich bekomme jedoch folgende Fehlermeldung:
        #1248 - Every derived table must have its own alias
        Hat jemand ne Idee was das heißt?

        Comment


        • #5
          ich häng mal meine drei Tabellen dran! die DB heißt bei mir "modules"! Leider akzeptiert er kein *.sql kann man ja umbenennen! Danke im Vorraus!!
          Attached Files

          Comment


          • #6
            Originally posted by Taramsis View Post
            Vielen Dank für deine Hilfe! Ich bekomme jedoch folgende Fehlermeldung:

            #1248 - Every derived table must have its own alias
            Hat jemand ne Idee was das heißt?
            Das der Alias fehlt

            Code:
            SELECT min(X.TaskStart)  FROM  
            (    SELECT * FROM m1    
                 UNION ALL    
                 SELECT * FROM m2    
                UNION ALL    
                SELECT * FROM m3  
             ) AS X
             WHERE taskstart = 0

            Comment


            • #7
              achso muss es nicht heißen "WHERE TaskProcessed = 0" statt "WHERE TaskStart = 0"!

              Comment


              • #8
                Hi,

                wie es ebis geschrieben hat klappts, aber wie würde ich es mit fanderlf Anfrage machen.
                Code:
                UPDATE m1 SET X.TaskProcessed = true WHERE X.TaskStart =
                (
                  SELECT min(Y.TaskStart)
                  FROM
                  (
                    SELECT * FROM m1
                    UNION ALL
                    SELECT * FROM m2
                    UNION ALL
                    SELECT * FROM m3
                  )AS Y
                  WHERE X.TaskProcessed = 0
                )AS X
                leider klappt das obige nicht!
                #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS X' at line 13

                Comment


                • #9
                  versuch mal:

                  [highlight=sql]
                  WITH taskmin AS
                  (
                  SELECT min(TaskStart) AS taskstart
                  FROM
                  (
                  SELECT TaskStart FROM
                  (
                  SELECT TaskStart FROM m1
                  ) as m1TaskStart
                  UNION ALL
                  SELECT TaskStart FROM
                  (
                  SELECT Taskstart FROM m2
                  ) as m2TaskStart
                  UNION ALL
                  SELECT TaskStart FROM
                  (
                  SELECT TaskStart FROM m3
                  ) as m3TaskStart
                  )
                  WHERE taskstart = 0
                  )
                  UPDATE m1 SET TaskProcessed = true WHERE TaskStart = taskmin.taskstart
                  UPDATE m2 SET TaskProcessed = true WHERE TaskStart = taskmin.taskstart
                  UPDATE m3 SET TaskProcessed = true WHERE TaskStart = taskmin.taskstart
                  [/highlight]

                  Comment


                  • #10
                    #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WITH taskmin AS
                    (
                    SELECT min(TaskStart) AS taskstart
                    FROM
                    (
                    SELEC' at line 1
                    Hat es bei dir geklappt?
                    (Weiter oben hatte ich ja die drei Tabellen gepostet!)

                    Comment


                    • #11
                      Die Lösung von fanderlf hat was, allerdings kann Deine mySql nix mit einer CTE anfangen wie Deine Fehlermeldung besagt...

                      Comment


                      • #12
                        Dann könnte man immer noch erstere Lösung verwenden. Der Unterschied ist "nur", dass bei der zweiten Lösung die mindestzeit nur einmal berechnet wird und bei der ersten jedesmal.

                        Bei der ersten Lösung kann es allerdings vorkommen, dass mehrere Zeilen auf 1 gesetzt werden, da die SQL Kommandos ja nacheinander abgearbeitet werden. Wenn nun beim ersten schon ein Wert auf 1 gesetzt wird, dann ändert sich das kleinste Datum in der 2. Abfrage...

                        btw. bezeichnet man ein "with ... as " konstrukt als CTE? Wie heisst denn das Teil genau? Mir ists letztes mal nicht eingefallen.

                        Comment


                        • #13
                          Originally posted by fanderlf View Post
                          Wie heisst denn das Teil genau? Mir ists letztes mal nicht eingefallen.
                          CTE =Common Table Expressions

                          Comment


                          • #14
                            Ah super danke wollte ich schon lang mal wissen nach was ich suchen muss, wenn ich da mal problem hab.
                            Gehen eigentlich auch mehrere CTEs in einer Abfrage? Kann mich erinnern, dass ich da mal Probleme hatte.

                            Comment


                            • #15
                              Sicher:
                              Code:
                              with sub1 as(...), 
                                  sub2 as(...),
                                  sub3 as(...),...
                              Dim
                              Zitat Tom Kyte:
                              I have a simple philosophy when it comes to the Oracle Database: you can treat it as a black box and just stick data into it, or you can understand how it works and exploit it as a powerful computing environment.

                              Comment

                              Working...
                              X