Hank: Ähnliche Queries ergeben unterschiedliche Ergebnisse

Frohes Neues an alle,

ich habe 2 Abfragen, bei denen ich mir ein ähnliches Ergebnis erwarte, aber in einem Fall 660 betroffene Artikel angezeigt bekomme und im anderen fall 0.

SELECT
    *
FROM
    _prefix_artikel a
INNER JOIN _prefix_artikel_temp t ON
    a.LieferantenID = t.LieferantenID AND a.Artikelnummer = t.Artikelnummer
WHERE
    a.LieferantenID = 1000;

ergibt 660 Artikel.

UPDATE
    _prefix_artikel a
INNER JOIN _prefix_artikel_temp t ON
    a.LieferantenID = t.LieferantenID AND a.Artikelnummer = t.Artikelnummer
SET
    a.Bemerkung = t.Bemerkung
WHERE
    a.LieferantenID = 1000

ergibt 0 Artikel.

mal vom SELECT und UPDATE abgesehen. Wo ist der Unterschied zwischen diesen Queries?

Hank

  1. Mangels Testdaten und genauerer Ausführung, welches „sql“ überhaupt gemeint ist und ob es vielleicht Fehlermeldungen gab, habe ich keine Ahnung. Aber diese Beispiele ohne die „hirnwegknallenden“ Aliase funktionieren mit MariaDB 10.7.4

    https://www.mysqltutorial.org/mysql-update-join/

    Tipp: Schreibe doch mal - in (D)einer SQL-Shell das Zauberwort „EXPLAIN“ vor der Query...

    1. Mangels Testdaten und genauerer Ausführung, welches „sql“ überhaupt gemeint ist und ob es vielleicht Fehlermeldungen gab, habe ich keine Ahnung. Aber diese Beispiele ohne die „hirnwegknallenden“ Aliase funktionieren mit MariaDB 10.7.4

      https://www.mysqltutorial.org/mysql-update-join/

      Hallo Willi,

      MariaDB auch bei mir. Die Queries laufen auch beide fehlerfrei.
      Nur hat der SELECT 660 Treffer und der UPDATE 0 Treffer.

      Testdaten kann ich Dir keine geben, aber sind die wichtig? Mir fehlt der logische Ansatz, warum da überhaupt etwas unterschiedliches rauskommen kann?

      Was gefällt die an den Aliassen nicht?

      a für Tabelle Artikel
      t für Tabelle Temp

      Hank

      1. Was gefällt die an den Aliassen nicht?

        Das ich mir diese genau merken muss. Das ist in meinen Augen „notlos unfallträchtig“.

      2. Testdaten kann ich Dir keine geben, ... Die Queries laufen auch beide fehlerfrei.

        Wie schon geschrieben: EXPLAIN hilft zu erkennen, was die MariaDB daraus macht.

      3. Moin,

        Nur hat der SELECT 660 Treffer und der UPDATE 0 Treffer.

        Was meinst du genau mit „Treffer“? Ein UPDATE-Query liefert keine Daten, die Datenbank meldet hier nur wie viele Datensätze geändert wurden – und selbst wenn die Bedingung auf mehrere Datensätze zutrifft kann es eben trotzdem sein dass kein Datensatz geändert wurde und du eine 0 bekommst.

        Gruß
        Tobias

        1. Hallo Tobias,

          Was meinst du genau mit „Treffer“? Ein UPDATE-Query liefert keine Daten, die Datenbank meldet hier nur wie viele Datensätze geändert wurden – und selbst wenn die Bedingung auf mehrere Datensätze zutrifft kann es eben trotzdem sein dass kein Datensatz geändert wurde und du eine 0 bekommst.

          Stimmt. So weit habe ich noch nicht gedacht. Ich kann mir aber nicht vorstellen, dass alle Spalten der potentiell zu ändernden Rows identisch ist.
          Trotzdem hast Du recht, das sollte ich als "Fehlerquelle" ausschließen, indem ich bspw. in einem der Datensätze eine Spalte manipuliere.

          Hank

          1. Hallo Tobias,

            Was meinst du genau mit „Treffer“? Ein UPDATE-Query liefert keine Daten, die Datenbank meldet hier nur wie viele Datensätze geändert wurden – und selbst wenn die Bedingung auf mehrere Datensätze zutrifft kann es eben trotzdem sein dass kein Datensatz geändert wurde und du eine 0 bekommst.

            Stimmt. So weit habe ich noch nicht gedacht. Ich kann mir aber nicht vorstellen, dass alle Spalten der potentiell zu ändernden Rows identisch ist.
            Trotzdem hast Du recht, das sollte ich als "Fehlerquelle" ausschließen, indem ich bspw. in einem der Datensätze eine Spalte manipuliere.

            Hank

            Hallo Tobias, Du hattest recht:

            Die Query

            UPDATE
                _prefix_artikel a
            INNER JOIN _prefix_artikel_temp t ON
                a.LieferantenID = t.LieferantenID AND a.Artikelnummer = t.Artikelnummer
            SET
                a.Bemerkung = "test"
            WHERE
                a.LieferantenID = 1000
            

            bringt 660 betroffene Rows. Hätte das n icht gedacht, weil im Original knapp 10 Spalten upgedatet werden. Scheinen also alle 10 Spalten identisch zu sein. Und da es sich um eine Preisliste handelt, vermute ich jetzt einfach mal, dass es sich um eine Preisliste handelt, die absolut identisch zur letzten Preisliste ist.

            Hank

            1. Hallo Hank,

              danke, dass Du das rückgemeldet hast und nicht einfach abgetaucht bist. Das machen viele anders!

              Rolf

              --
              sumpsi - posui - obstruxi
              1. Hallo Rolf,

                danke, dass Du das rückgemeldet hast und nicht einfach abgetaucht bist. Das machen viele anders!

                Im Gegenteil, mir war wichtig, Tobias' Info sofort zu testen, damit sich keiner Mühe macht, wo sie nicht nötig ist. Und falls sich einer Mühe macht, ist der auch auf die Zusatzinfo angewiesen, die sich aus Tobias' Hinweis ergibt.

                Danke an alle Mithelfer.

                Hank

  2. Hallo Hank,

    ich hätte 2 dumme Fragen, um Verständnsirrtümer auszuschließen.

    • bist Du sicher, dass diese _prefix_artikel_temp Tabelle (die sehr nach temporären Daten klingt), beide Male die gleichen Werte enthält?
    • Wie ist deine Aussage "Der Update liefert 0 Artikel" zu verstehen? UPDATE Befehle liefern niemals ein Result Set. Oder meinst Du mit 0 die Anzahl der vom UPDATE geänderten Rows?

    Wenn du den UPDATE von PHP aus machst, bekommst Du die Anzahl der geänderten Rows über mysqli_affected_rows($db), bzw. bei PDO in Form des Rückgabewertes von PDO::exec oder über PDOStatement::rowCount.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Hallo Rolf,

      • bist Du sicher, dass diese _prefix_artikel_temp Tabelle (die sehr nach temporären Daten klingt), beide Male die gleichen Werte enthält?

      Ja, die Tabelle heißt _temp, weil ich dort temporär Daten hinein schreibe. Nach dem möglichen Update wird diese tabelle weider geleert. Da es aber keine wirklich temporäre Tabelle ist, bin ich sicher, dass die Daten darin identisch sind.

      • Wie ist deine Aussage "Der Update liefert 0 Artikel" zu verstehen? UPDATE Befehle liefern niemals ein Result Set. Oder meinst Du mit 0 die Anzahl der vom UPDATE geänderten Rows?

      Richtig, ich meine die Anzahl der geänderten Rows.

      Hank

  3. Mit den Testdaten von dieser Seite ...

    https://www.mysqltutorial.org/mysql-update-join/

    und dieser SQL-Anweisung:

    MariaDB [test]> UPDATE employees
        INNER JOIN
           merits ON employees.performance = merits.performance 
        SET 
           salary = salary + salary * percentage;
    

    wird sichtbar, wie die MariaDB-Shell dabei hilft, das aufgetretene Problem („matches exists, but nothing to do) zu analysieren:

    Query OK, 6 rows affected (0.011 sec)
    Rows matched: 7  Changed: 6  Warnings: 0
    

    Query OK - Kein Fehler bei Syntax, Namen oder Datentypen.

    matched: 7 - Zeilen, die zum JOIN und zur WHERE-Clausel passen.

    Changed: 6 - Zeilen, die tatsächlich verändert wurden. Entspricht affected rows.

    Bevor jemand fragt: In der obigen Tabelle ist salary in einem Fall 0. 0+0*x=0, da gab es also nichts zu ändern.

    1. Hallo Willi,

      klasse, dass Du Dir die Mühe gemacht hast.

      wird sichtbar, wie die MariaDB-Shell dabei hilft, das aufgetretene Problem („matches exists, but nothing to do) zu analysieren:

      Query OK, 6 rows affected (0.011 sec)
      Rows matched: 7  Changed: 6  Warnings: 0
      

      Kannst Du mir nochmal erklären, woher Du diese Anzeige nimmst?

      Bei mir erscheint nur, wieviele Rows betroffen sind.

      SQL

      Server-Version: 10.4.24-MariaDB - mariadb.org binary distribution

      Hank

      1. Hallo

        wird sichtbar, wie die MariaDB-Shell dabei hilft, das aufgetretene Problem („matches exists, but nothing to do) zu analysieren:

        Query OK, 6 rows affected (0.011 sec)
        Rows matched: 7  Changed: 6  Warnings: 0
        

        Kannst Du mir nochmal erklären, woher Du diese Anzeige nimmst?

        Das stammt aus der MariaDB-Shell (analog zur MySQL-Shell). Die wird über ein Terminal (unter Windows: Eingabeaufforderung) aufgerufen. Das funktioniert nur, wenn man lokalen oder SSH-Zugriff auf die Maschine hat, auf der der DB-Server läuft.

        Bei mir erscheint nur, wieviele Rows betroffen sind.

        SQL

        Ja, in phpMyAdmin, nicht in der servereigenen Shell. phpMyAdmin ist eine Weboberfläche für den DB-Zugriff, das dem Nutzer (abgesehen vom Feature des Fernzugriffs über den Browser) die händische Eingabe ersparen will und soll. Dafür kennt das Tool nicht alle Möglichkeiten der DB-eigenen Shell.

        Eventuell kannst du eine Ausgabe, wie die von Raketenwilli über die diversen Schalter im SQL-Reiter, die per Checkbox aktiviert werden können, erreichen.

        Tschö, Auge

        --
        200 ist das neue 35.
        1. Das funktioniert nur, wenn man lokalen oder SSH-Zugriff auf die Maschine hat, auf der der DB-Server läuft.

          Fast alles richtig. Aber der mysql oder mariadb-client kann auch einzeln installiert werden. (Derzeit die Pakete mariadb-client-10.6 oder mysql-client-8.0)

        2. Hallo Auge, vielen Dank für die Erklärung. (natürlich auch an Raketenwilli). Hank