SQL - Обновление полей сопоставления полей из 2 других таблиц - PullRequest
1 голос
/ 03 июля 2019

Возможно, кофе еще не появился, но у меня возникли проблемы, когда я не могу понять, как выполнить обновление SQL.По сути, у меня есть 3 таблицы, и я пытаюсь обновить поле в таблице1 с данными в таблице2 на основе критериев в таблице 3.

Мои 3 таблицы с данными образца:

tblInvoiceDetail

keyID     InvoiceNumber      ItemID      Qty       Price
--------------------------------------------------------
1            200123          100001       4         400
2            200123          100002       1          10
3            200321          100001       1         100
4            200555          100002       2          20
5            200444          100003       4          20

tblInvoices

keyID      InvoiceNumber      InvoiceDate      CustomerID     InvoiceTotal
--------------------------------------------------------------------------
1            200123             3/15/19          456123           410
2            200321             5/31/19          123456           100
3            200555             6/30/19          111222           120
4            200444             6/31/19          111222            20 

tblItemUpdate

keyID       OldItem        NewItem
----------------------------------
1           100001         999001
2           100002         999002
3           100003         999003

Вот UPDATEзаявление, которое я пробовал, но оно не обновляет все записи, которые я ожидал.

UPDATE 
    tblInvoiceDetail
SET 
    tblInvoiceDetail.ItemID = tblItemUpdate.NewItem
FROM 
    tblInvoiceDetail
INNER JOIN 
    tblItemUpdate ON tblInvoiceDetail.ItemID = tblItemUpdate.OldItem
INNER JOIN 
    tblInvoices ON tblInvoiceDetail.InvoiceNumber = tblInvoices.InvoiceNumber
WHERE
    tblInvoices.InvoiceDate < '2019-06-25'

Я подозреваю, что проблема в моих JOIN, поэтому она не соответствует всем нужным записям.

Я хочу изменить ItemID в tblInvoiceDetail, и я хочу, чтобы он нашел совпадение в tblItemUpdate.OldItem и изменил его на значение в tblItemUpdate.NewItem ,Однако я хочу обновить ItemID только в том случае, если tblInvoices.InvoiceDate предшествует 6/25/19.

Итак, с моими примерами данных в tblInvoiceDetail только ключевые идентификаторы 1, 2 иНеобходимо обновить 3.

У меня много записей в моей действующей базе данных, поэтому я могу указать на одну конкретную вещь, которая не работает.Я только что нашел несколько счетов, которые, по моему мнению, должны были измениться, но не изменились.

Ответы [ 2 ]

1 голос
/ 03 июля 2019

Стандартный способ написать это с помощью подзапросов:

UPDATE tblInvoiceDetail
SET ItemID = (SELECT NewItem FROM tblItemUpdate WHERE OldItem = tblInvoiceDetail.ItemID)
WHERE InvoiceNumber IN (
    SELECT id.InvoiceNumber
    FROM tblInvoiceDetail AS id INNER JOIN tblItemUpdate AS iu ON id.ItemID = iu.OldItem
    WHERE id.InvoiceDate < CAST('2019-06-25' AS DATE)
);

Ezlo уже указал на проблему, когда при присоединении к обновленной таблице создано несколько строк.

EDIT:

Если присмотреться к вашим данным, я также вижу, что у вас возникла более серьезная проблема при сопоставлении ItemID с правильными счетами. Первичный ключ в tblInvoiceDetail является составной частью InvoiceNumber и ItemID, но у вас, похоже, нет этой информации в списке из tblItemUpdate.

Поскольку ваши данные выборки содержат недопустимую дату 31 июня, естественно задаться вопросом, возникает ли проблема сравнения строк. Проблема первичного ключа может привести к большему количеству накладных, чем предполагалось, поэтому она не объяснит вашу проблему, описанную как меньшее количество строк, обновляющихся, чем ожидалось.

0 голосов
/ 03 июля 2019

Я хочу изменить ItemID в tblInvoiceDetail, и я хочу, чтобы он нашел совпадение в tblItemUpdate.OldItem и изменил его на значение в tblItemUpdate.NewItem

Пока:

UPDATE D SET 
    ItemID = U.NewItem
FROM 
    tblInvoiceDetail AS D
    INNER JOIN tblItemUpdate AS U ON D.ItemID = U.OldItem

Однако я хочу обновить ItemID, только если tblInvoices.InvoiceDate предшествует 6/25/19.

Вы можете проверить существование с помощью EXISTS:

UPDATE D SET 
    ItemID = U.NewItem
FROM 
    tblInvoiceDetail AS D
    INNER JOIN tblItemUpdate AS U ON D.ItemID = U.OldItem
WHERE
    EXISTS (SELECT NULL FROM tblInvoices AS I WHERE 
            I.InvoiceNumber = D.InvoiceNumber AND -- Link the invoice to update (D) to the invoice table (I)
            I.InvoiceDate < '2019-06-25')

Будьте осторожны с типом данных InvoiceDate.Это должно быть DATE (или DATETIME), а не VARCHAR, потому что это будет проблематично, если вы сравните его со значением в противном случае ('6/25/19' и '2019-06-25' обе даты, но они совершенно разные строки ).

Также остерегайтесь существования нескольких строк с одинаковым значением OldItem в tblItemUpdate, так как вы можете присоединиться к определенной строке из tblInvoiceDetail против N из tblItemUpdate, и в этом случае окончательное значение NewItem, которое будет обновлено, равно неопределено .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...