Update aller Felder, wenn FeldX den Wert 1 hat

Hallo MySQl-Fachleute!

In folgender MySql-Tabelle „products_to_categories“

Produkt-ID | Produkt-Kategorie(n) | flag(bolean)

soll
1.) für alle Einträge flag auf FALSE gesetzt werden, wenn eine bestimmte ProduktID-Kategorie Kombination existiert
2.) nur für die eine Kombination soll flag dann auf TRUE gesetzt werden.

Mein Ansatz, allerdings ohne die If-Abfrage
1.)
UPDATE products_to_categories
SET flag = FALSE WHERE products_id = 1;
-> hier müsste zuvor abgefragt werden, ob der folgende Eintrag existiert:
WHERE products_id = 1 AND categories_id = 9

2.)
UPDATE products_to_categories
SET flag = TRUE WHERE products_id = 1 AND categories_id = 9;

Leider habe ich sehr wenig Ahnung von MySQL, konnte aber auch im iNet und in Fachbüchern nichts passendes finden…

Vielen Dank für Eure Hilfe!!!

  • Mathias -

Hab jetzt selbst eine Lösung gefunden, die funktioniert. Aber ob das alles so ok ist und es da nicht ne kürzere Variante gibt…?

1.)
Es wir bei allen Einträgen mit product_id=1 flag=FALSE gesetzt, wenn ein Eintrag mit product_id=1 und categories_id=9 existiert (und nur dann).
2.)
Bei dem Eintrag products_id = 2 and categories_id = 9 wird flag=TRUE gesetzt

1.)
UPDATE products_to_categories
SET flag = FALSE
WHERE products_id = 1
AND exists (
SELECT p.products_id, p.categories_id
FROM (SELECT * FROM products_to_categories)
AS p where p.products_id = 1 and p.categories_id = 9
);

2.)
UPDATE products_to_categories
SET flag = TRUE
WHERE products_id = 2 and categories_id = 9;

Hatte irgendwo gelesen, dass innerhalb von UPDATE nicht noch mal dieselbe Tabelle in einen SELECT-Aufruf darf.
Das lässt sich umgehen, indem man einen Alias für die Tabelle anlegt.

Hi, wenn ich’s richtig verstanden haben möchstest du zwei UPDATE statements vermeiden. Du kannst dazu das CASE Konstrukt benutzt um so die Fallunterscheidung einzubauen:

UPDATE prodcuts_to_categories SET
flag = CASE
WHEN products _id = 1 AND categories_id = 9 THEN TRUE
ELSE FALSE
END

Gruß Holger

Vielen Dank für die Antwort,
ganz passt Dein Vorschlag leider noch nicht.

Die Abfrage soll lauten:

WENN EIN EINTRAG EXISTIERT MIT:
products _id = 1 AND categories_id = 9

UPDATE
flag = FALSE WHERE products _id = 1

sowie

UPDATE
flag = TRUE WHERE products _id = 1 AND categories_id = 9

Ich hatte weiter oben selbst eine Variante gepostet, die funktioniert, aber vielleicht viel zu umständlich ist.

Geht das kürzer/besser ?

Danke

  • Mathias -

Du kannst auch mehrere Bedingungen angeben:

UPDATE prodcuts_to_categories SET
flag = CASE
WHEN products_id = 1 AND categories_id = 9 THEN TRUE
WHEN products_id = 1 THEN FALSE
END

Das entspricht dem, was du in zwei Statements updatest. Aber was soll in der Spalte flag stehen, wenn die product_id nicht 1 ist? Null? Oder auch „false“? Tip: Ich würde immer noch ein ELSE einfügen, damit es eindeutiger ist.

Hallo Holger,

da fehlt halt (meines Wissens) immernoch die IF-Abfrage
Ob ein Eintrag existiert mit
products _id = 1 AND categories_id = 9

Nur dann sollen die zwei UPDATEs stattfinden.
Bei Einträgen mit products_id != 0 soll sich nichts ändern.

Im zweiten Beitrag hatte ich das mit exists (
SELECT p.products_id, p.categories_id…) gelöst. Da aber nicht zweimal dieselbe Tabelle innerhalb einer verschachtelten Abfrage stehen darf, ist der Code etwas lang und undurchsichtig geworden.

Hast Du noch eine Idee, oder verstehe ich es nicht richtig???

Danke

  • Mathias -

Deine IF Abfrage entspricht doch dem " … CASE
WHEN products_id = 1 AND categories_id = 9 THEN …"

Nur wenn beide Bedingungen „product_id = 1“ und „categories_id = 9“ erfüllt sind, nur dann wird TRUE in die spalte flag geupdatet.

Sorry, bin mir immer noch nicht sicher…

flag=FALSE soll für
ALLE Einträge mit product_id=1
gesetzt werden,
aber nur wenn EIN Eintrag mit
products_id = 1 AND categories_id = 9
existiert

Ansonsten bleibt alles wie es ist.
In Deinem Code würde immer für alle flag=FALSE gesetzt werden, wenn sie die product_id=1 haben - oder?

Die Abfrage nach der Existenz eines Eintrags mit
products_id = 1 AND categories_id = 9
muss aber vorher stattfinden und erfüllt sein.

(PS: hatte mich vorhin vertippt, sollte products_id != 1 sein)

Tausen Dank für die Mühe!!!

Nein, da die Bedinungen von „oben nach unten“ abgearbeitet werden. Trifft die 1. Bedingung zu, wird die 2. nicht mehr verarbeitet. Trifft die 1. Bedingung nicht zu, wird die 2. abgefragt usw…

Genial…
kein Wunder dass ich das nicht verstanden hatte, von diesem Bedingungsablauf wusste ich nichts.

Leider ist die offizielle MySQL-Doku für mich als Anfänger vollig undurchsichtig.

Vielen herzlichen Dank für die Geduld!
Ich teste das sofort, das macht den Code viel übersichtlicher.

Beste Grüße

  • Mathias -

Mist, geht doch noch nicht,

Du schreibst:
Trifft die 1. Bedingung zu,
wird die 2. nicht mehr verarbeitet.

Es soll aber so sein dass auch die zweite verarbeitet wird, wenn die 1. zutrifft (und nur dann)

Im Moment wird aber die zweite Bedingung ausgeführt, wenn die erste NICHT zutrifft

UPDATE products_to_categories
SET main_category = CASE
WHEN products_id = 1 AND categories_id = 15 THEN 1
WHEN products_id = 1 THEN NULL
END

???

Sorry, aber deine Bedingungen ergeben für mich dann keinen Sinn mehr. Ich denke ich habe dir von der Syntax helfen können, aber was du da inhaltlich vorhast erschließt sich mir nicht.

Ich kanns nur immer wieder versuchen zu erleutern,
jetzt mal in Textform:

Wenn in der Tabelle ein Eintrag existiert mit
product_id = 1 and categories_id = 15

dann:
setze bei diesem Datensatz flag = TRUE
und:
setze bei allen weiteren Datensätze mit product_id=1 das flag = FALSE

Was ist da unklar?

>>>>>
Pro Produkt-ID darf es nur einmal flag=TRUE geben,
und es muss immer ein Eintrag mit flag=TRUE existieren.
Soll flag geändert werden, z.B. auf categories_id=15, muss erst geprüft werden, ob es diese Kombination auch gibt.
Sonst würden bei allen Einträgen flag=FALSE gesetzt werden, obwohl es keinen neuen Eintrag mit flag=TRUE gibt.
Das darf aber nicht vorkommen.

(Ich glaub, mit jedem Erklärungsversuch klingt es komplizierter…)

Sorry…