MySQL 5.0.67 | Hilfe bei SQL-Aufgabenstellung
heinetz
- datenbank
Hallo Forum,
ich versuche mal die Aufgabe auf ein Beispiel zu reduzieren:
Es gibt ein Tabelle 'products', in der, was sonst, Produkte
als Datensätze gespiechert werden. Diese Produkte kennzeichnet
das Feld 'id' als eindeutiger Schlüssel. Da die Produkte in
einer bestimmten Reihenfolge angezeigt werden sollen, gibt es
ausserdem ein Feld 'position'.
Jetzt wird es etwas komplizierter:
Produkte sind entweder (Haupt-)Produkte einer 'Wahrengruppe',
oder (Unter-)Produkte eines anderen Produkts. Es gibt also noch
zwei Felder 'group_key' und 'group_value'.
Die Tabelle sieht folgendermassen aus:
+----------+------------+-------------+----------+
| id | group_key | group_value | position |
+==========+============+=============+==========+
| 52 | products | 41 | 2 |
+----------+------------+-------------+----------+
| 47 | waregroups | 2 | 1 |
+----------+------------+-------------+----------+
| 44 | waregroups | 1 | 1 |
+----------+------------+-------------+----------+
| 43 | products | 41 | 1 |
+----------+------------+-------------+----------+
| 41 | waregroups | 1 | 2 |
+----------+------------+-------------+----------+
| 61 | products | 47 | 1 |
+----------+------------+-------------+----------+
Es gibt also die 3 (Haupt-)produkte 47, 44, 41,
zu dem (Haupt-)produkt 47 das (Unter-)produkt 61 und
zu dem (Haupt-)produkt 41 die (Unter-)produkte 43 und 52
Die 'position' beschreibt die Position innerhalb der
Gruppe. Beispielsweis ist die Position des (Haupt-)produkts
44 dessen Position innerhalb der Wahrengruppe 1, die
Position des (Unter-)produkts 43 dessen Position innerhalb
des übergeordneten (Haupt-)produkts 41.
Jetzt zu meiner Aufgabe:
------------------------
Die Produkte 44 und 41 haben hierrarchisch die gleiche
Qualität. Sie sind beide Produkte der Warengruppe 1. Die
Reihenfolge innerhalb der Gruppe, also das Feld 'position',
legt fest, dass 44 an erster und 41 an zweiter Stelle
angezeigt wird und die will ich ändern!
41 soll an die erste Stelle und 44 an die zweite rücken.
Das geht ja erstmal einfach:
die Position 1 erstmal freimachen:
UPDATE `products` SET `position` = '2' WHERE `products`.`id` =44;
die Position neu belegen:
UPDATE `products` SET `position` = '1' WHERE `products`.`id` =41;
Jetzt weiss ich aber nicht, ob und wenn dann welches Produkt
die erste Stelle besetzt. Ich kenne nur den Datensatz, des
Produkts 41. Die Aufgabe lautet also eigentlich:
41 soll an die erste Stelle und das Produkt dieser Gruppe,
was im Moment diese Stelle besetzt, soll an die Stelle von
41 rücken.
Ich müsste also erst die id des Produkts herausfinden, dass die
position 1 besetzt und mir diese merken. Dann müsste ich die
jetzige Position des Produkts 41 herausfinden und mir die merken.
Dann könnte ich mit den beiden Werten, die ich in Variablen
zwischenspeichern müsste die zwei SQL-Statements zusammenbauen.
Ich frage mich, ob das mit einem ausgefeilten SQL-Statement,
vielleicht mit Subselect, geht. Ich habe folgendes probiert:
die Position 1 freimachen:
UPDATE `products`
SET `position` =
(SELECT `position` FROM `products` WHERE `products`.`id` = 41)
WHERE `products`.`id` =44;
... das funktionierte erstmal nicht ;(
Kann mir dabei jemand weiter helfen ?
danke und
beste gruesse,
heinetz
yo,
Kann mir dabei jemand weiter helfen ?
weiß nicht genau, ob mysql das inzwischen kann....
UPDATE products p
SET position = CASE
WHEN p.id <> 41 THEN (SELECT p2.Position
FROM products p2
WHERE p2.id = 41
)
ELSE 1
END
WHERE p.id IN (SELECT 41
FROM dual -- das ist Oracle, keine ahnung für mysql
UNION ALL
SELECT p2.id
FROM products p2
WHERE p2.group_key = p.group_key
AND p2.group_value = p.group_value
AND p2.position = 1
)
;
Ilja
Hi!
weiß nicht genau, ob mysql das inzwischen kann....
Nein. Das Ändern von Tabellen beim gleichzeitigen Abfragen derselben in einer Subquery ist nicht möglich. Man könnte sich aber zu Fuß eine temporäre Tabelle als Zwischenspeicher anlegen.
CASE
WHEN [...] THEN [...]
ELSE 1
END
So ein einteiliges CASE-WHEN-ELSE kann man auch mit der IF()-Funktion abkürzen.
[...] SELECT 41 FROM dual -- das ist Oracle, keine ahnung für mysql [...]
MySQL kann auch ohne FROM selektieren. Das Hilfskonstrukt "dual" benötigt man nicht.
Lo!
yo,
Nein. Das Ändern von Tabellen beim gleichzeitigen Abfragen derselben in einer Subquery ist nicht möglich.
hmm, da muss mysql dann noch mal nachlegen.
So ein einteiliges CASE-WHEN-ELSE kann man auch mit der IF()-Funktion abkürzen.
gibt sicherlich viele wege für eine fallunterschiedung, ich mag die case variante, da sie so oftmals in allen rdbms unterstützt wird.
MySQL kann auch ohne FROM selektieren. Das Hilfskonstrukt "dual" benötigt man nicht.
und da sollte oracle endlichmal nachlegen, den unsiin mit dual lassen. aber 11.2g ist ja gerade erst rausgekommen....
Ilja
Hallo Jungs,
dahinter dass ich kein Subselect auf die Tabelle ausführen
kann, die ich updaten will, bin ich dann auch gekommen.
Danke für eure Beiträge. Mein Problem sitzt tiefer ;(
beste gruesse,
heinetz