Linuchs: mySQL UPDATE abhängig von anderen Tabellen

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

  1. 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.

    1. Hallo dedlfix,

      Ich würde sagen, du denkst nur nicht logisch.

      Nein, nein, Sie denken nicht, Sie sind nur logisch.

      • Niels Bohr zu Albert Einstein, als der die Quantentheorie ablehnte[1]

      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

      --
      sumpsi - posui - clusi

      1. Hab ich aus Michio Kaku, Im Hyperrraum; steht auf englisch bei wikiquote ↩︎

      1. 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

        1. 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.

  2. 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