Ähnliche Queries ergeben unterschiedliche Ergebnisse
Hank
- sql
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
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...
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
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
Was gefällt die an den Aliassen nicht?
Das ich mir diese genau merken muss. Das ist in meinen Augen „notlos unfallträchtig“.
Testdaten kann ich Dir keine geben, ... Die Queries laufen auch beide fehlerfrei.
Wie schon geschrieben: EXPLAIN hilft zu erkennen, was die MariaDB daraus macht.
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
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,
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
Hallo Hank,
danke, dass Du das rückgemeldet hast und nicht einfach abgetaucht bist. Das machen viele anders!
Rolf
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
Hallo Hank,
ich hätte 2 dumme Fragen, um Verständnsirrtümer auszuschließen.
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
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
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.
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.
Server-Version: 10.4.24-MariaDB - mariadb.org binary distribution
Hank
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.
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
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)
Hallo Auge, vielen Dank für die Erklärung. (natürlich auch an Raketenwilli). Hank