SQL-更新其他2个表中的字段匹配字段

时间:2019-07-03 14:55:45

标签: sql-server

也许还没有开始喝咖啡,但是我很难解决如何完成SQL更新的问题。本质上,我有3个表,并且尝试根据表3中的条件使用表2中的数据更新表1中的字段。

我的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

tbl发票

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中,所以它与我想要的所有记录都不匹配。

我想在tblInvoiceDetail中更改 ItemID ,并且希望它在 tblItemUpdate.OldItem 中找到匹配项,并将其更改为 tblItemUpdate.NewItem中的值。但是,我只想在 tblInvoices.InvoiceDate 在19/25/19之前更新ItemID。

因此,使用我的示例数据在tblInvoiceDetail中,只需更新keyID 1、2和3。

我的实时数据库中有很多记录,因此我可以指出1项无效的特定内容。我刚刚发现了一些我认为应该更改但没有更改的发票。

2 个答案:

答案 0 :(得分:1)

编写此代码的标准方法是使用子查询:

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已经指出了在连接到已更新的表中创建多行时的问题。

编辑:

仔细查看您的数据,我还发现您在将ItemID与正确的发票匹配时遇到了更大的问题。 tblInvoiceDetail中的主键是InvoiceNumberItemID的组合,但您似乎没有从tblItemUpdate的列表中找到该信息。

由于示例数据包含6月31日的无效日期,因此很自然地想知道是否存在字符串比较问题。主键问题可能会索要比预期更多的发票,因此不会解释您的问题,因为行更新少于预期。

答案 1 :(得分:0)

  

我想更改tblInvoiceDetail中的ItemID,并希望它找到   tblItemUpdate.OldItem中的匹配项并将其更改为   tblItemUpdate.NewItem

到目前为止:

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

但是,我只想在tblInvoices.InvoiceDate时更新ItemID   是19年6月25日之前。

您可以使用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中的特定行与tblItemUpdate中的N连接起来在这种情况下,将要更新的最终NewItem值为 indetermined