SQL UPDATE Czy jedna kolumna ma być równa wartości w powiązanej tabeli, do której odwołuje się inna kolumna?


112

Mam nadzieję, że to miało sens, pozwól mi rozwinąć:

Istnieje tabela danych śledzenia dla programu quizu, w której każdy wiersz zawiera ...

QuestionID i AnswerID (dla każdego istnieje tabela). Tak więc z powodu błędu było kilka QuestionID ustawionych na NULL, ale QuestionID powiązanego AnswerID znajduje się w tabeli Answers.

Powiedzmy więc, że QuestionID to NULL, a AnswerID to 500, jeśli przejdziemy do tabeli Answers i znajdziemy AnswerID 500, to jest kolumna z QuestionID, która powinna być tam, gdzie jest wartość NULL.

Zasadniczo chcę ustawić każdy NULL QuestionID na równy QuestionID znaleziony w tabeli Answers w wierszu Answer identyfikatora odpowiedzi, który znajduje się w tabeli śledzenia (ten sam wiersz, co NULL QuestionID, który jest zapisywany).

Jak bym to zrobił?

UPDATE QuestionTrackings
SET QuestionID = (need some select query that will get the QuestionID from the AnswerID in this row)
WHERE QuestionID is NULL AND ... ?

Nie wiem, jak będę w stanie przypisać QuestionID do QuestionID z pasującego AnswerID ...


MySQL i Microsoft SQL Server obsługują rozszerzenia składni SQL w celu obsługi aktualizacji wielu tabel. Inne marki nie. Nie powiedziałeś, jakiej marki bazy danych używasz.
Bill Karwin

Odpowiedzi:


171
update q
set q.QuestionID = a.QuestionID
from QuestionTrackings q
inner join QuestionAnswers a
on q.AnswerID = a.AnswerID
where q.QuestionID is null -- and other conditions you might want

Przed uruchomieniem aktualizacji polecam sprawdzić, jaki jest zestaw wyników do aktualizacji (to samo zapytanie, tylko z zaznaczeniem):

select *
from QuestionTrackings q
inner join QuestionAnswers a
on q.AnswerID = a.AnswerID
where q.QuestionID is null -- and other conditions you might want

W szczególności, czy każdy identyfikator odpowiedzi ma zdecydowanie tylko 1 powiązany identyfikator pytania.


7
Nie jestem pewien, dlaczego, ale to nie działa w moim przypadku, jednak działa: update QuestionTrackings q inner join QuestionAnswers a on q.AnswerID = a.AnswerID set q.QuestionID = a.QuestionID; wydaje się, że to to samo podstawowe zapytanie w innej kolejności. jakiś pomysł, dlaczego?
billynoah

2
@billynoah, ORA-00971: brak słowa kluczowego SET w Oracle
masT

2
Masz problem z podobną sytuacją w PhpMyAdmin przez MySQL. W moim przypadku kolumny źródłowa i docelowa znajdują się w tej samej tabeli, ale wybór rekordu jest oparty na drugiej tabeli. Wersja zapytania „SELECT” działa, ale instrukcja UPDTATE zgłasza błąd składni w „FROM”
2NinerRomeo

3
UPDATE table1 NATURAL JOIN table2 SET table1.col1 = table1.col2 WHERE table2.col3 ="condition"
Pokonałem

czy „q” z „update q” w odpowiedzi jest dosłownym parametrem zapytania, czy jest to tylko skrót nazwy tabeli?
Shawn

28

Bez notacji aktualizuj i dołączaj (nie wszystkie DBMS obsługują to), użyj:

UPDATE QuestionTrackings
   SET QuestionID = (SELECT QuestionID
                        FROM AnswerTrackings
                        WHERE AnswerTrackings.AnswerID = QuestionTrackings.AnswerID)
   WHERE QuestionID IS NULL
     AND EXISTS(SELECT QuestionID
                        FROM AnswerTrackings
                        WHERE AnswerTrackings.AnswerID = QuestionTrackings.AnswerID)

Często w zapytaniu takim jak to trzeba zakwalifikować klauzulę WHERE za pomocą klauzuli EXISTS, która zawiera zapytanie podrzędne. Zapobiega to deptaniu przez UPDATE wierszy, w których nie ma dopasowania (zwykle zeruje wszystkie wartości). W tym przypadku, ponieważ brakujący identyfikator pytania zmieniłby NULL na NULL, prawdopodobnie nie ma to znaczenia.


Ta metoda działała dla mnie na Oracle 12c (gdzie metoda update-join zawiodła).
shwartz

16

Nie wiem, czy napotkasz ten sam problem co ja w MySQL Workbench, ale uruchomienie zapytania z instrukcją INNER JOINafter FROMnie zadziałało dla mnie. Nie mogłem uruchomić zapytania, ponieważ program skarżył się na rozszerzenieFROM instrukcję.

Aby zapytanie działało, zmieniłem je na

UPDATE table1 INNER JOIN table2 on table1.column1 = table2.column1
SET table1.column2 = table2.column4
WHERE table1.column3 = 'randomCondition';

zamiast

UPDATE a
FROM table1 a INNER JOIN table2 b on a.column1 = b.column1
SET a.column2 = b.column4
WHERE a.column3 = 'randomCondition';

Myślę, że moje rozwiązanie jest właściwą składnią dla MySQL.


Tak, wygląda na to, że dla Mysql JOIN jest traktowane jako część zapytania „table_references”. Dołącz do MySQL
AWP

12
UPDATE
    "QuestionTrackings"
SET
    "QuestionID" = (SELECT "QuestionID" FROM "Answers" WHERE "AnswerID"="QuestionTrackings"."AnswerID")
WHERE
    "QuestionID" is NULL
AND ...

1
Pracował dla mnie nad wyrocznią. Odpowiedź @ eglasius nie.
Lombas,

7

Miałem to samo pytanie. Oto działające rozwiązanie, które jest podobne do rozwiązania Eglasius. Używam postgresql.

UPDATE QuestionTrackings
SET QuestionID = a.QuestionID
FROM QuestionTrackings q, QuestionAnswers a
WHERE q.QuestionID IS NULL

Narzeka, że ​​zamiast nazwy tabeli w linii 1 użyto q, aw linii 2 nic nie powinno poprzedzać QuestionID.


3
 select p.post_title,m.meta_value sale_price ,n.meta_value   regular_price
    from  wp_postmeta m 
    inner join wp_postmeta n
      on m.post_id  = n.post_id
    inner join wp_posts p
      ON m.post_id=p.id 
    and m.meta_key = '_sale_price'
    and  n.meta_key = '_regular_price'
     AND p.post_type = 'product';



 update  wp_postmeta m 
inner join wp_postmeta n
  on m.post_id  = n.post_id
inner join wp_posts p
  ON m.post_id=p.id 
and m.meta_key = '_sale_price'
and  n.meta_key = '_regular_price'
 AND p.post_type = 'product'
 set m.meta_value = n.meta_value;

3

W przypadku MySQL możesz użyć tego zapytania

UPDATE tabela1 a, tabela2 b SET a.coloumn = b.coloumn WHERE a.id = b.id


1

Zaktualizuj dane drugiej tabeli w pierwszej tabeli, aby połączyć wewnętrzne przed ustawieniem SET:

`UPDATE `table1` INNER JOIN `table2` ON `table2`.`id`=`table1`.`id` SET `table1`.`name`=`table2`.`name`, `table1`.`template`=`table2`.`template`;

1

poniżej działa dla mysql

update table1 INNER JOIN table2 on table1.col1 =  table2.col1
set table1.col1 =  table2.col2

0

Myślę, że to powinno działać.

UPDATE QuestionTrackings
SET QuestionID = (SELECT QuestionID
                  FROM AnswerTrackings
                  WHERE AnswerTrackings.AnswerID = QuestionTrackings.AnswerID)
WHERE QuestionID IS NULL
AND AnswerID IS NOT NULL;
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.