mySQL UPDATE abhängig von anderen Tabellen
Linuchs
- sql
Moin,
Besucher einer Messe sollen einen Vermerk in ihren Stammsatz (adr1) bekommen, wenn weder Kontaktwünsche (kon1) noch Eventwünsche (evb1) gespeichert sind.
SQL-Fehlermeldung: #1241 - Operand should contain 1 column(s)
Hatte ich schon befürchtet, aber der Unter-select kommt mit diesem einen Feld nicht aus, die Anzahl der Wünsche müssen ermittelt werden:
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# merkmalsleiste Stelle 5 auf E (Erinnern) setzen
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UPDATE tm_adressen adr1
SET adr1.merkmalsleiste = CONCAT( SUBSTRING(merkmalsleiste,1,4), 'E' )
WHERE adr1.owner_id = '17'
AND adr1.id =
(
SELECT
adr1.id
,adr1.bezeichnung
,adr1.nname
,adr1.vname
,COUNT(kon1.besucher_id) anzahl_kontaktwuensche
,COUNT(evb1.adress_id) anzahl_eventwuensche
FROM tm_adressen adr1
LEFT JOIN tm_kontakte kon1
ON kon1.besucher_id = adr1.id
AND kon1.prio_1 = '1' # Aussteller-Wuensche ignorieren
LEFT JOIN tm_eventbuchungen evb1
ON evb1.adress_id = adr1.id
WHERE adr1.owner_id = '17'
AND adr1.adr_kz = 2
GROUP BY adr1.id
HAVING anzahl_kontaktwuensche = 0 AND anzahl_eventwuensche = 0
)
Folgende Variante erzeugt #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 'SELECT adr2.id ,adr2.bezeichnung ,adr2.nname ,adr2.vname ,COUNT(kon1.besuc' at line 9
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# merkmalsleiste Stelle 5 auf E (Erinnern) setzen
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UPDATE tm_adressen adr1
SET adr1.merkmalsleiste = CONCAT( SUBSTRING(merkmalsleiste,1,4), 'E' )
WHERE adr1.owner_id = '17'
AND adr1.id = adr2.id
(
SELECT
adr2.id
,adr2.bezeichnung
,adr2.nname
,adr2.vname
,COUNT(kon1.besucher_id) anzahl_kontaktwuensche
,COUNT(evb1.adress_id) anzahl_eventwuensche
FROM tm_adressen adr2
LEFT JOIN tm_kontakte kon1
ON kon1.besucher_id = adr2.id
AND kon1.prio_1 = '1' # Aussteller-Wuensche ignorieren
LEFT JOIN tm_eventbuchungen evb1
ON evb1.adress_id = adr2.id
WHERE adr2.owner_id = '17'
AND adr2.adr_kz = 2
GROUP BY adr2.id
HAVING anzahl_kontaktwuensche = 0 AND anzahl_eventwuensche = 0
)
denke ich zu kompliziert? Habe im Netz kein vergleichbares Beispiel gefunden.
Gruß, Linuchs
Tach!
Besucher einer Messe sollen einen Vermerk in ihren Stammsatz (adr1) bekommen, wenn weder Kontaktwünsche (kon1) noch Eventwünsche (evb1) gespeichert sind.
EXISTS beziehungsweise NOT EXISTS existieren.
SQL-Fehlermeldung:
#1241 - Operand should contain 1 column(s)
Hatte ich schon befürchtet, aber der Unter-select kommt mit diesem einen Feld nicht aus, die Anzahl der Wünsche müssen ermittelt werden:
UPDATE tm_adressen adr1 SET adr1.merkmalsleiste = CONCAT( SUBSTRING(merkmalsleiste,1,4), 'E' ) WHERE adr1.owner_id = '17' AND adr1.id = ( SELECT adr1.id ,adr1.bezeichnung ,adr1.nname ,adr1.vname ,COUNT(kon1.besucher_id) anzahl_kontaktwuensche ,COUNT(evb1.adress_id) anzahl_eventwuensche FROM tm_adressen adr1 [...]
Was soll denn dabei rauskommen? Du hast da einen Vergleich à la X = Y und gibst für Y eine Ergebnismenge aus, die größer als eine Zeile und eine Spalte ist. Wie soll ein Einzelwert gegen viele verglichen werden? Man kann X oder Y als Subquery besorgen, aber die darf dann auch nur einen einzelnen Wert als Ergebnis haben, sprich: eine Zeile, ein Wert.
Folgende Variante erzeugt
#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 'SELECT adr2.id ,adr2.bezeichnung ,adr2.nname ,adr2.vname ,COUNT(kon1.besuc' at line 9
AND adr1.id = adr2.id ( SELECT [...]
Was soll denn mit dem Ergebnis der Subquery passieren? Klar ist das ein Syntaxfehler. Sowas würde auch in natürlicher Sprache keinen gescheiten Satz ergeben.
denke ich zu kompliziert?
Ich würde sagen, du denkst nur nicht logisch. Du hast zwar eingangs den Anwendungsfall von außen betrachtet beschrieben. Aber nun musst du ihn auch aus technischer Sicht beschreiben. Welche(r) Wert(e) soll aus welchen Tabellen/Spalten/Funktionen genommen werden und mit welchem anderen Wert verglichen werden, oder was auch immer?
dedlfix.
Hallo dedlfix,
Ich würde sagen, du denkst nur nicht logisch.
Nein, nein, Sie denken nicht, Sie sind nur logisch.
Linuchs schrub:
wenn weder Kontaktwünsche (kon1) noch Eventwünsche (evb1) gespeichert sind.
Das müsste viel einfacher und auch performanter mit EXISTS sein:
WHERE ...
AND NOT EXISTS(SELECT ... für die Kontaktwünsche)
AND NOT EXISTS(SELECT ... für die Eventwünsche)
Diese Teilselects solltest Du hinreichend minimalistisch gestalten können, ggf. sogar so dass sie keinen JOIN mehr brauchen.
Rolf
Hab ich aus Michio Kaku, Im Hyperrraum; steht auf englisch bei wikiquote ↩︎
Hallo Rolf, danke für die Idee. So funktioniert es wunderbar:
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# merkmalsleiste Stelle 5 auf E (Erinnern) setzen
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UPDATE ".$db[0]['adressen']." adr1
SET adr1.merkmalsleiste = CONCAT( SUBSTRING(merkmalsleiste,1,4), 'E' )
WHERE adr1.owner_id = '".$owner_id."'
AND adr1.adr_kz = 2
AND SUBSTRING(adr1.merkmalsleiste,2,1) = '".$arr_in['tranche_nr']."'
AND NOT EXISTS( SELECT kon1.besucher_id
FROM ".$db[0]['kontakte']." kon1
WHERE kon1.besucher_id = adr1.id
AND kon1.prio_1 = '1' ) # Aussteller-Wuensche prio_3 ignorieren
AND NOT EXISTS( SELECT evb1.adress_id
FROM ".$db[0]['eventbuchungen']." evb1
WHERE evb1.adress_id = adr1.id )
Linuchs
Tach!
AND NOT EXISTS( SELECT kon1.besucher_id FROM ".$db[0]['kontakte']." kon1 WHERE kon1.besucher_id = adr1.id AND kon1.prio_1 = '1' ) # Aussteller-Wuensche prio_3 ignorieren
Bei einer Subquery mit EXISTS kannst du auch einfach SELECT * FROM ...
schreiben. Die Feldliste wird in dem Fall nämlich ignoriert, und es hat keinen Sinn, sich dort die Mühe zu geben, etwas konkretes aufzuführen.
dedlfix.
Hi,
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # merkmalsleiste Stelle 5 auf E (Erinnern) setzen # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ UPDATE tm_adressen adr1 SET adr1.merkmalsleiste = CONCAT( SUBSTRING(merkmalsleiste,1,4), 'E' )
Autsch. Dein Datenmodell ist kaputt - Du speicherst offensichtlich verschiedene Informationen in einer Spalte.
AND adr1.id = adr2.id ( SELECT
zusammengefaßt: AND adr1.id = adr2.id(SELECT
Vielleicht erkennst Du so besser, worin das Problem besteht.
cu,
Andreas a/k/a MudGuard