Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Wewnętrzne kroki aktualizacji dołączenia MYSQL

Dla "zapytania nie aktualizuje poprawnie wierszy":

Chcesz zaktualizować kolumnę b do minimum z b dla wszystkich wierszy mających ten sam a

Zaproponowałeś użycie następującego JOIN aby to zrobić:

UPDATE test.tem t1
  JOIN test.tem t2
    ON t1.a = t2.a
SET t1.b = t2.b
WHERE t1.b > t2.b
     OR t1.b IS NULL;

Wbrew temu, co myślisz, JOIN nie wykona 1-1 JOIN . W rzeczywistości jest to JOIN od jak powiedziałem wczoraj nie używasz klucza podstawowego (ani unikalnego klucza innego niż null) w klauzuli przyłączenia.

W rzeczywistości przepisując to zapytanie jako SELECT prawdopodobnie pomoże ci zrozumieć problem:

SELECT t1.a as t1a, t1.b as t1b, t2.a as t2a,t2.b as t2b FROM tem t1 JOIN tem t2
    ON t1.a = t2.a
WHERE t1.b > t2.b
     OR t1.b IS NULL;

+------+---------+------+--------+
| T1A  |  T1B    | T2A  |  T2B   |
+------+---------+------+--------+
|   1  | (null)  |   1  | 2      |
|   1  | 2       |   1  | 1      |
|   1  | (null)  |   1  | 1      |
|   1  | (null)  |   1  | (null) |
+------+---------+------+--------+

http://sqlfiddle.com/#!2/856a7/8

Jak zobaczysz, wiersz (1, null) dopasuj (1, 1) , (1, 2) i (1, null) . W zależności od (niedeterministycznej) kolejności wykonywania zapytania, może to przypisać dowolną z trzech możliwych wartości dla b (nie jestem tego pewien, ale może nawet aktualizując kilka czasy). W pewnym stopniu miałeś szczęście, że podczas testowania znalazłeś „niewłaściwy” wynik!

Mam nadzieję, że to wyjaśnia nieco więcej, dlaczego zapytanie nie przynosi oczekiwanego rezultatu. Ponieważ wielostołowy UPDATE oświadczenia nie zezwalają na ORDER BY ani GROUP BY klauzul, tak jak ja, aby znaleźć „dobry” wynik, nie widzę wielu innych opcji niż znalezienie minimum pierwszego poprzez podzapytanie...



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. utrwalaj java LocalDate w MySQL

  2. Jak załadować dane do tabeli mysql, ale zignorować puste linie?

  3. Korzystanie z łączenia wewnętrznego w celu określenia odstępu między określonymi rekordami i powiązanymi zdarzeniami w tabeli

  4. Ściągawka z wydajnością MySQL

  5. mysql - czy mogę zapytać ile connect_errors podał dany host?