lixx: DELETE mit einem subquery

Hallo!

Folgendes Problem: Ich möchte mittels Subquery einen Datensatz in MySQL v4.1 löschen. Nun habe ich folgendes gefunden, da MySQL das nicht so ohne weiteres macht.

UPDATE t ... WHERE col = (SELECT (SELECT ... FROM t...) AS _t ...);

Soweit mein Englisch reicht steht dort, dass wenn man die FROM-Klausel auch als Subquery löst, dass es dann funzen sollte.

Mein Befehl sieht nun fogendermassen aus - und funzt nicht:

DELETE FROM t1 WHERE id IN ( SELECT ( SELECT id FROM t1 ) AS _tt WHERE _tt.id IN ( 10420, 10242, 10444 ) );

DELETE FROM t1 WHERE id IN ( SELECT id FROM ( SELECT id FROM t1 ) AS _tt WHERE id IN ( 10878, 10997, 11055 ) )

Kann mir bitte jemand weiterhelfen, was ich dabei falsch mache? Oder funktoniert das nur bei UPDATE und nicht bei DELETE?

lg lixx

  1. Hi,

    Mein Befehl sieht nun fogendermassen aus - und funzt nicht:

    selbst wenn Du "funzt" in ein der deutschen Sprache inhärentes Wort übersetzt, ist das noch keine Fehlerbeschreibung.

    Oder funktoniert das nur bei UPDATE und nicht bei DELETE?

    Der letzte Satz auf der zugehörigen Dokumentationsseite dürfte erhellend sein.

    Cheatah

    --
    X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
    1. selbst wenn Du "funzt" in ein der deutschen Sprache inhärentes Wort übersetzt, ist das noch keine Fehlerbeschreibung.

      Weiß nicht was du damit meinst ...

      Oder funktoniert das nur bei UPDATE und nicht bei DELETE?

      Der letzte Satz auf der zugehörigen Dokumentationsseite dürfte erhellend sein.

      Der letzte Satz hier http://dev.mysql.com/doc/refman/4.1/en/update.html würde sich aber mit http://dev.mysql.com/doc/refman/4.1/en/subquery-restrictions.html widersprechen ...

      "
      Exception: The preceding prohibition does not apply if you are using a subquery for the modified table in the FROM clause. Example:

      UPDATE t ... WHERE col = (SELECT (SELECT ... FROM t...) AS _t ...);

      Here the prohibition does not apply because a subquery in the FROM clause is materialized as a temporary table, so the relevant rows in t have already been selected by the time the update to t takes place.
      "

      Somit verdunkelt sich die Sache wieder ;)

      lg lixx

      1. Hallo Forum,

        "
        Exception: The preceding prohibition does not apply if you are using a subquery for the modified table in the FROM clause. Example:

        UPDATE t ... WHERE col = (SELECT (SELECT ... FROM t...) AS _t ...);

        Somit verdunkelt sich die Sache wieder ;)

        Warum? Da steht doch ganz genau, dass das bei Updates gilt.
        Bei Delete gilt das nicht, da gelten andere Regeln.

        Gruß
        Alexander Brock

        1. Exception: The preceding prohibition does not apply if you are using a subquery for the modified table in the FROM clause. Example:

          UPDATE t ... WHERE col = (SELECT (SELECT ... FROM t...) AS _t ...);

          Warum? Da steht doch ganz genau, dass das bei Updates gilt.
          Bei Delete gilt das nicht, da gelten andere Regeln.

          Kommt aber nicht klar rüber. Eine Modifizierung einer Tabelle ist ja auch das Löschen eines Datensatzes und man kann annehmen, dass hier nur ein Beispiel der UPDATE-Klausel verwendet wurde. Das die Ausnahme NUR für UPDATE gilt steht dort nicht.

          1. Lassen wir die DELETE-Klausel einmal aussen vor. Jetzt habe ich es mit dem Beispiel aus der Dokumentation versucht, das eigentlich gehen sollte.

            UPDATE t ... WHERE col = (SELECT (SELECT ... FROM t...) AS _t

            mein MySQL-Befehl:

            UPDATE t1 SET col='aaa' WHERE id = ( SELECT ( SELECT id FROM t1 ) AS _t WHERE _t.id ='11064' );

            Gibt folgende Fehlermeldung aus:

            "
            #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 'WHERE _t.id='11064' )' at line 2
            "

            Zweiten Variante:

            UPDATE t1 SET col='aaa' WHERE id = ( SELECT ( SELECT id FROM t1 WHERE id='11064' ) AS _t );

            "
            #1093 - You can't specify target table 't1' for update in FROM clause
            "

            Irgendwo mache ich da was falsch.

            lg lixx

            1. Hallo

              Lassen wir die DELETE-Klausel einmal aussen vor. Jetzt habe ich es mit dem Beispiel aus der Dokumentation versucht, das eigentlich gehen sollte.

              UPDATE t ... WHERE col = (SELECT (SELECT ... FROM t...) AS _t

              mein MySQL-Befehl:

              UPDATE t1 SET col='aaa' WHERE id = ( SELECT ( SELECT id FROM t1 ) AS _t WHERE _t.id ='11064' );

              erstens ist die Anweisung fehlerhaft, zweitens ist sie unsinnig.

              Schauen wir uns das im Detail an:

              1. Fehler

                
              UPDATE t1                  -- Du möchtest Inhalte von Tabelle t1 modifizieren  
              SET col='aaa'  
              WHERE id = (  
                  SELECT (  
                      SELECT id FROM t1  -- Dann solltest Du im Subselect einen Tabellenalias verwenden  
                  ) AS _t  
                  WHERE _t.id ='11064'  
              )  
              
              

              #1093 - You can't specify target table 't1' for update in FROM clause

              Logisch. Die Fehlermeldung käme auch, wenn nicht schon vorher ein Fehler wäre.

              2. Fehler:

                
              UPDATE t1                  -- Du möchtest Inhalte von Tabelle t1 modifizieren  
              SET col='aaa'              -- und zwar die Werte in den Zeilen, deren id  
              WHERE id = (               -- bestimmten Werten entspricht  
                  SELECT (               -- Dein Subselect ergibt zwar nur einen Wert  
                      SELECT id FROM t1  -- dennoch ist das ein Syntax-Verstoß, weil  
                  ) AS _t                -- das auf Zufall beruht  
                  WHERE _t.id ='11064'   -- Verwende IN statt =  
              )  
              
              

              3. Unsinn

              Warum ein doppelt geschachteltes Subselect, wenn es ein einfache IN täte?

                
              UPDATE t1  
              SET col='aaa'  
              WHERE id IN (<Liste der entsprechenden id-Werte>) -- hier einer  
              
              

              Wenn Du in Wirklichkeit etwas anderes machen möchtest, dann hast Du Dein Beispiel auf unzulässige Weise vereinfacht. Gib in diesem Fall an, wie Deine Tabelle wirklich aussieht und wie Deine Kriterien wirklich aussehen.

              Ich verstehe jedenfalls nicht, was Du vorhast.

              Freundliche Grüße

              Vinzenz

              1. Ich verstehe jedenfalls nicht, was Du vorhast.

                Mist! Jetzt habe ich mich völlig verhaschpelt! Wofür ich es benötige sind eh zwei Tabellen im Spiel ... aber sowas von verrannt!

                Sorry, wegen den Umständen.

                lg lixx

      2. echo $begrüßung;

        Somit verdunkelt sich die Sache wieder ;)

        Du zitierst hier nur aus dem Handbuch. Was hat dein Versuch ergeben?
        ("Funzt nicht" und dergleichen ist kein gültiges negatives Versuchsergebnis. Ein gültiges wäre eine Beschreibung deiner Beobachtung. Die Helfenden interessiert vor allem: Was kam statt des erwarteten Ergebnisses (z.B. Wortlaut der Fehlermeldung)?)

        echo "$verabschiedung $name";