kolumna aktualizacji mysql z wartością z innej tabeli


221

Mam dwa stoliki, oba wyglądają tak

id  name  value
===================
1   Joe     22
2   Derk    30

Muszę skopiować wartość valuez tableAna tableBna podstawie nazwy czeku w każdej tabeli.

Wszelkie wskazówki dotyczące tego UPDATEoświadczenia?

Odpowiedzi:


412

Oprócz tej odpowiedzi, jeśli chcesz dynamicznie zmienić wartość tableB.value zgodnie z wartością tableA.value, możesz na przykład:

UPDATE tableB
INNER JOIN tableA ON tableB.name = tableA.name
SET tableB.value = IF(tableA.value > 0, tableA.value, tableB.value)
WHERE tableA.name = 'Joe'

tak, INNER JOINjest idealny w tej sytuacji. CONCAT_WS
— Zwykłem

2
Czy można to zrobić za pomocą aliasów?
— Gellie Ann

Próbowałem tego, ale bez powodzenia, ponieważ liczba „dotkniętych wierszy” daje mi 5690, ale suma wierszy wynosi 59643, dlaczego? oto zapytanie:UPDATE participants_registrations INNER JOIN participants ON participants.id = participants_registrations.participantId INNER JOIN registrations ON registrations.id = participants_registrations.registrationId LEFT JOIN groups ON (groups.id = registrations.groupId) SET registrations.groupId = groups.id, registrations.groupName = groups.name, participants.memberOfGroupName = groups.name
— Wielki Sfinks

To nie działa tabela B wciąż ma swoje dane bez zmian. wtools.io/paste-code/bzWA Próbka oparta na OP i tej odpowiedzi.
— sniffingdoggo

157

musisz dołączyć do dwóch tabel:

na przykład chcesz skopiować wartość namez tabeli A do tableBmiejsca, w którym mają taką samą wartośćID

UPDATE tableB t1 
        INNER JOIN tableA t2 
             ON t1.id = t2.id
SET t1.name = t2.name 
WHERE t2.name = 'Joe'

AKTUALIZACJA 1

UPDATE tableB t1 
        INNER JOIN tableA t2 
             ON t1.id = t2.id
SET t1.name = t2.name 

AKTUALIZACJA 2

UPDATE tableB t1 
        INNER JOIN tableA t2 
             ON t1.name = t2.name
SET t1.value = t2.value

1
Mam ponad 1 000 rekordów z różnymi nazwami i wartościami, oto twoje powiedzenie tylko dla 1 rekordu
— LeoSam

możesz po prostu usunąć whereklauzulę lub zmodyfikować ją w wherezależności od potrzeb.
— John Woo

również tabela B ma więcej rekordów niż tabela A, moim pomysłem jest sprawdzenie z tabeli B do a jeśli nazwa istnieje, skopiuj wartość „wartość” do tabeli B,!
— LeoSam

nie wiem, czy dobrze zrozumiałem twoje pytanie, czy możesz sprawdzić moją zaktualizowaną odpowiedź?
— John Woo

próbowałem obu aktualizacji, drugi mówi, że wykonano w 734 wierszach, sprawdziłem wartości nadal wszystkie 0 nie zmieniło się
— LeoSam

91

Druga możliwość to

UPDATE TableB 
SET TableB.value = (
    SELECT TableA.value 
    FROM TableA
    WHERE TableA.name = TableB.name
);

7
Tak, nie ma potrzeby skomplikowanych połączeń, gdy wszystko, czego potrzebujemy, to zaktualizować pole o wartość z innej tabeli.
— davidkonrad

8
Tak, to działa dobrze, ale jest bardzo, bardzo wolne w przypadku dużych zestawów danych. Jeśli pracujesz z małymi stolikami, ta metoda jest w porządku, ale zalecam ŁĄCZENIE, jak pokazano powyżej dla czegokolwiek innego.
— frijj2k

Ponadto w tym scenariuszu tabela A i B nie mogą być tą samą tabelą z powodu ograniczeń SQL.
— Muhwu

@ frijj2k, czy byłoby to nadal powolne, jeśli .namejest indeksowane w obu tabelach?
— Steverino,

3

Druga opcja jest możliwa również w przypadku korzystania z trybu bezpiecznych aktualizacji (i pojawia się błąd wskazujący, że próbujesz zaktualizować tabelę bez GDZIE, w którym użyto kolumny KLUCZ), dodając:

UPDATE TableB  
SET TableB.value = (  
SELECT TableA.value  
    FROM TableA  
    WHERE TableA.name = TableB.name  
)  
**where TableB.id < X**  
;

2
    UPDATE    cities c,
          city_langs cl
    SET       c.fakename = cl.name
   WHERE     c.id = cl.city_id

1

Przechowuj swoje dane w tabeli temp

Select * into tempTable from table1

Teraz zaktualizuj kolumnę

 UPDATE table1
    SET table1.FileName = (select FileName from tempTable where tempTable.id = table1.ID);

0

W moim przypadku przyjęte rozwiązanie było po prostu zbyt wolne. W przypadku tabeli zawierającej 180 000 wierszy szybkość aktualizacji wynosiła około 10 wierszy na sekundę. Dotyczy to indeksów elementów łączenia.

W końcu rozwiązałem problem, stosując procedurę:

CREATE DEFINER=`my_procedure`@`%` PROCEDURE `rescue`()
BEGIN
    declare str VARCHAR(255) default '';
    DECLARE n INT DEFAULT 0;
    DECLARE i INT DEFAULT 0;
    DECLARE cur_name VARCHAR(45) DEFAULT '';
    DECLARE cur_value VARCHAR(10000) DEFAULT '';
    SELECT COUNT(*) FROM tableA INTO n;
    SET i=0;
    WHILE i<n DO 
      SELECT namea,valuea FROM tableA limit i,1 INTO cur_name,cur_value;
      UPDATE tableB SET nameb=cur_name where valueb=cur_value;
      SET i = i + 1;
    END WHILE;

END

Mam nadzieję, że pomoże to w przyszłości tak, jak mi pomogło


-4

Jeśli masz wspólne pole w obu tabelach, to takie proste! ....

Tabela 1 = tabela, w której chcesz zaktualizować. Tabela 2 = tabela, z której pobierasz dane.

  1. wykonaj zapytanie w tabeli 1 i znajdź wspólną wartość pola.
  2. wykonaj pętlę i znajdź wszystkie dane z tabeli 2 zgodnie z wartością z tabeli 1.
  3. ponownie wykonaj zapytanie o aktualizację w tabeli 1.

$qry_asseet_list = mysql_query("SELECT 'primary key field' FROM `table-1`");

$resultArray = array();
while ($row = mysql_fetch_array($qry_asseet_list)) {
$resultArray[] = $row;
}



foreach($resultArray as $rec) {

    $a = $rec['primary key field'];

    $cuttable_qry = mysql_query("SELECT * FROM `Table-2` WHERE `key field name` = $a");

    $cuttable = mysql_fetch_assoc($cuttable_qry);



    echo $x= $cuttable['Table-2 field']; echo " ! ";
    echo $y= $cuttable['Table-2 field'];echo " ! ";
    echo $z= $cuttable['Table-2 field'];echo " ! ";


    $k = mysql_query("UPDATE `Table-1` SET `summary_style` = '$x', `summary_color` = '$y', `summary_customer` = '$z' WHERE `summary_laysheet_number` = $a;");

    if ($k) {
        echo "done";
    } else {
        echo mysql_error();
    }


}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.