Neuigkeiten:

Ist euer Problem gelöst, dann bitte den Knopf "Thema gelöst" drücken!

Mobiles Hauptmenü

SQL - die vierte Runde UPDATE

Begonnen von Elwood, August 21, 2011, 15:48:16

⏪ vorheriges - nächstes ⏩

Elwood

Irgendwann lerne ich SQL schon noch. Irgendwann  ::)

Ich habe folgendes Statement
      SELECT [CC-firmen].ID
                   FROM (
                                SELECT DISTINCT [CC-firmen].ID, [CC-firmen].Sperre
                                FROM (([CC-firmen]
                                LEFT JOIN Ansprechpartner ON [CC-firmen].ID = Ansprechpartner.ID_CC)
                                LEFT JOIN Kategorie ON [CC-firmen].ID = Kategorie.ID_CC)
                                LEFT JOIN Kontakte ON Ansprechpartner.ID = Kontakte.ID_AP
                   WHERE Kontakte.Kuerzel="WW"
                                 )
     WHERE  [CC-firmen].ID = [CC-firmen].ID AND  [CC-firmen].Sperre = False; 

Das liefert mir ein paar Datensätze des Feldes [CC-firmen].ID
Nun möchte ich zu diesen Sätzen die entsprechenden Felder "Sperre" auf True setzen.
Also etwa so:
UPDATE [CC-firmen] SET [CC-firmen].Sperre = True
Aber wie bekomme ich die beiden zusammen? Alle bisherigen Versuche sind irgendwo gescheitert...

ebs17

Was willst Du da zusammenbringen?
...
FROM [CC-firmen] LEFT JOIN ...

Alle für linke Seite heißt alle, auch wenn Du eine Tabelle auf der rechten Seite noch zusätzlich filterst. Das hatten wir doch schon einmal. Vergessen oder nicht verstanden?

Also wäre an die Aktualisierungsabfrage ein passender Filter einfach anzuhängen, ohne Selbstverständlichkeiten wie ...
WHERE  [CC-firmen].ID = [CC-firmen].ID

MfGA
ebs

Elwood

Stimmt, so ähnlich hatten wir das schon.
Im Select Statement können noch andere Kriterien auftauchen, die die Joins benötigen.
Möglich, dass es auch Ohne LEFT klappt, aber das kann ich später noch versuchen. Erst mal liefert mir das
(leicht geändert)
      (SELECT [CC-firmen].ID
                   FROM (
                                SELECT DISTINCT [CC-firmen].ID, [CC-firmen].Sperre
                                FROM (([CC-firmen]
                                LEFT JOIN Ansprechpartner ON [CC-firmen].ID = Ansprechpartner.ID_CC)
                                LEFT JOIN Kategorie ON [CC-firmen].ID = Kategorie.ID_CC)
                                LEFT JOIN Kontakte ON Ansprechpartner.ID = Kontakte.ID_AP
                   WHERE Kontakte.Kuerzel="WW" AND  [CC-firmen].Sperre = False
                                 ))
das richtige Ergebnis.
schreibe ich das UPDATE aber drum rum
UPDATE [CC-firmen] SET [CC-firmen].Sperre = True FROM
      (SELECT [CC-firmen].ID
                   FROM (
                                SELECT DISTINCT [CC-firmen].ID, [CC-firmen].Sperre
                                FROM (([CC-firmen]
                                LEFT JOIN Ansprechpartner ON [CC-firmen].ID = Ansprechpartner.ID_CC)
                                LEFT JOIN Kategorie ON [CC-firmen].ID = Kategorie.ID_CC)
                                LEFT JOIN Kontakte ON Ansprechpartner.ID = Kontakte.ID_AP
                   WHERE Kontakte.Kuerzel="WW" AND  [CC-firmen].Sperre = False
                                 ))
WHERE  [CC-firmen].ID = [CC-firmen].ID;

bekomme ich für das erste FROM eine Fehlermedung: Fehlender Operator.
Und muss ich für ein [CC-firmen].ID nicht ein Alias setzen? Aber wo?

ebs17

ZitatIm Select Statement können noch andere Kriterien auftauchen, die die Joins benötigen.
Willst Du jetzt eine Auswahl- oder eine Aktualisierungsabfrage?

Wenn es nach Titel eine Aktualisierungsabfrage sein soll, wiederhole ich meine Aussage zum LEFT JOIN - die Worte sind wohl angekommen, die Aussage wohl noch nicht.

Zitatbekomme ich für das erste FROM eine Fehlermedung
Das hat auch in einer Aktualisierungsabfrage nichts zu suchen. Ich empfehle, Grundlagen und grundlegende Syntax anzuschauen.

MfGA
ebs

Elwood

#4
Hi,
Das mit dem LEFT JOIN verstehe ich schon. Nur zählen erst mal Ergebnisse.
Das Ergebnis möchte ich nun als Bedingung für die Aktualsierung.

Dein Tipp zur grundlegenden Syntax ist jetzt nicht wirklich hilfreich.
Wie sieht dann das korrekte WHERE aus?
Wenn ich das so mache UPDATE [CC-firmen] SET [CC-firmen].Sperre = True
WHERE [CC-firmen].ID =
     (SELECT [CC-firmen].ID
                   FROM (
                                SELECT DISTINCT [CC-firmen].ID, [CC-firmen].Sperre
                                FROM (([CC-firmen]
                                LEFT JOIN Ansprechpartner ON [CC-firmen].ID = Ansprechpartner.ID_CC)
                                LEFT JOIN Kategorie ON [CC-firmen].ID = Kategorie.ID_CC)
                                LEFT JOIN Kontakte ON Ansprechpartner.ID = Kontakte.ID_AP
                   WHERE Kontakte.Kuerzel="WW" AND  [CC-firmen].Sperre = False
                                 )
        ); 

Bekomme ich die Meldung "Höchstens ein Datensatz kann von dieser Unterabfrage ausgewählt werden."

ebs17

WHERE ID = ...
=> ID kann nur einen Wert annehmen, die Datensatzgruppe in der Unterabfrage liefert aber offensichtlich mehrere, was die Fehlermeldung aussagt.
WHERE ID IN (SELECT ID FROM ...)
... könnte mit mehreren umgehen. Alternativ könnte man EXISTS einsetzen.
ZitatDein Tipp zur grundlegenden Syntax ist jetzt nicht wirklich hilfreich.
Immerhin konntest Du der Hauptabfrage das Angesicht einer Aktualisierungsabfrage geben, und das selbständig. Da nenne ich eine Aufmunterung durchaus hilfreicher als eine Vorlage zum "blinden" Kopieren.
ZitatNur zählen erst mal Ergebnisse.
Zählst Du Ergebnisse nach Zeilen und Länge der SQL-Anweisung?
UPDATE [CC-firmen] SET [CC-firmen].Sperre = True
WHERE [CC-firmen].Sperre = False

Diese Abfrage liefert genau das gleiche Resultat wie jenes, was gewünscht aus Deiner Anweisung lesbar ist. Wie bereits gesagt, die LEFT JOINS sind unnötige Schattenspiele, unberücksichtigt bleibt unberücksichtigt, auch wenn man ein paar zusätzliche Kringel dranmalt.

MfGA
ebs

ebs17

Nachtrag bzgl. "Ergebnisse zählen": Mir fehlt die Vorstellung, wie man Abfragen anders als ergebnisorientiert erstellt. Daneben zählen noch Performance und Schlankheit/Einfachheit.

MfGA
ebs

Elwood

Finally! Danke!
Das "IN" bringt's! Ich hatte schon mit EXISTS rumprobiert, aber das hatte im Ergebnis auch nur einen Satz.
So klappt es nun:
1 UPDATE [CC-firmen] SET [CC-firmen].Sperre = True
2 WHERE [CC-firmen].ID IN
3                    (SELECT [CC-firmen].ID
4                    FROM (
5                                 SELECT DISTINCT [CC-firmen].ID, [CC-firmen].Sperre
6                                FROM (([CC-firmen]
7                                 LEFT JOIN Ansprechpartner ON [CC-firmen].ID = Ansprechpartner.ID_CC)
8                                 LEFT JOIN Kategorie ON [CC-firmen].ID = Kategorie.ID_CC)
9                                 LEFT JOIN Kontakte ON Ansprechpartner.ID = Kontakte.ID_AP
10                   WHERE Kontakte.Kuerzel="WW" AND  [CC-firmen].Sperre = False
11                                 )
12                   );

Dabei bekomme ich aus der Abfrage in 5-9 alle Daten, auf die ich später möglicherweise einschränken will.
(Das Statement wird in einem Suchformular gebaut)
In Zeile 10 filtere ich auf die Sätze, die ich benötige. (Nur so kann ich mir erklären, warum das rauskommt, was ich will)
Zeile 3 und 4 kann ich mir tatsächlich sparen.

Vielen Dank für den nächtlichen Tipp!