通过匹配发票ID更新表

时间:2017-02-28 21:31:59

标签: sql oracle

我有一个可能是一个简单的问题。我的表是一个月内的发票集合。我的表中的ship_to_state列仅显示每张发票上一行的实际发货状态。我需要更新我的表,以便为该发票上的每个GL帐户行项目显示发货到州的值。现在,它只出现在我的12000-99 GL帐户中。

这是我当前的查询:

UPDATE INVOICES
SET SHIP_TO_STATE = 
(SELECT SHIP_TO_STATE FROM INVOICES WHERE GL_ACCOUNT_ID = '12000-99' 
AND INVOICES.INVOICE_ID = INVOICES.INVOICE_ID);

这是我的表:

CUSTOMER_ID INVOICE_ID  ITEM_ID GL_ACCOUNT_ID   SHIP_TO_STATE
Customer1   38441        ADM       46000-99 
Customer1   38441        ADM       12000-99         GA
Customer2   42809        GSD307    40100-02 
Customer2   42809        GSD310    40100-01 
Customer2   42809        GSW311    40100-01 
Customer2   42809        GSD200    40100-01 
Customer2   42809        FSR270    40100-02 
Customer2   42809        ADM       12000-99         WA
Customer3   42810        GSS10-100 40100-01 
Customer3   42810        GSS10-500 40100-05 
Customer3   42810        GSD210    40100-01 
Customer3   42810        ADM       45100-99 
Customer3   42810        ADM       12000-99         AL
Customer4   42811        PSG550-L  40100-02 
Customer4   42811        PSG550-M  40100-02 
Customer4   42811        ADM       12000-99         GA
Customer5   42812        GSS10-100 40100-01 
Customer5   42812        GSS10-350 40100-05 
Customer5   42812        GSD200    40100-01 
Customer5   42812        ADM       12000-99         NC
Customer6   42813        FSF105    40100-02 
Customer6   42813        FSF135    40100-02 
Customer6   42813        GSD310    40100-01 
Customer6   42813        GSW311    40100-01 
Customer6   42813        GSD190    40100-01 
Customer6   42813        GSW312    40100-01 
Customer6   42813        ADM       45100-99 
Customer6   42813        ADM       12000-99        TX

我期待着您的反馈。感谢。

4 个答案:

答案 0 :(得分:1)

UPDATE INVOICES
SET SHIP_TO_STATE = 
(SELECT MAX(SHIP_TO_STATE) FROM INVOICES i WHERE i.INVOICE_ID = INVOICES.INVOICE_ID);

每个发票ID只返回一条记录,并修复了其他地方提到的别名问题。如果没有ship_to_state值,则它将使用NULL更新。如果有多个,它将​​按字母顺序选择后一个 - 如果这是一个问题,有办法解决。

答案 1 :(得分:0)

您可以使用MERGE语句(语法比通过连接或相关子查询更新更清晰)。下面的解决方案假设在当前表格中,每个invoice_id只有一个非空值。

语法可能有点过时(你没有提供测试数据*)。 * 我的意思是,没有CREATE TABLE和INSERT语句

merge into invoices i
  using ( select invoice_id, ship_to_state 
          from   invoices 
          where  ship_to_state is not null )  s
    on (i.invoice_id = s.invoice_id)
when matched then update
  set i.ship_to_state = s.ship_to_state
    where i.ship_to_state is null

答案 2 :(得分:0)

Oracle安装程序

CREATE TABLE INVOICES ( CUSTOMER_ID, INVOICE_ID, ITEM_ID, GL_ACCOUNT_ID, SHIP_TO_STATE ) AS
SELECT 'Customer1', 38441, 'ADM',       '46000-99', NULL FROM DUAL UNION ALL
SELECT 'Customer1', 38441, 'ADM',       '12000-99', 'GA' FROM DUAL UNION ALL
SELECT 'Customer2', 42809, 'GSD307',    '40100-02', NULL FROM DUAL UNION ALL
SELECT 'Customer2', 42809, 'GSD310',    '40100-01', NULL FROM DUAL UNION ALL
SELECT 'Customer2', 42809, 'GSW311',    '40100-01', NULL FROM DUAL UNION ALL
SELECT 'Customer2', 42809, 'GSD200',    '40100-01', NULL FROM DUAL UNION ALL
SELECT 'Customer2', 42809, 'FSR270',    '40100-02', NULL FROM DUAL UNION ALL
SELECT 'Customer2', 42809, 'ADM',       '12000-99', 'WA' FROM DUAL UNION ALL
SELECT 'Customer3', 42810, 'GSS10-100', '40100-01', NULL FROM DUAL UNION ALL
SELECT 'Customer3', 42810, 'GSS10-500', '40100-05', NULL FROM DUAL UNION ALL
SELECT 'Customer3', 42810, 'GSD210',    '40100-01', NULL FROM DUAL UNION ALL
SELECT 'Customer3', 42810, 'ADM',       '45100-99', NULL FROM DUAL UNION ALL
SELECT 'Customer3', 42810, 'ADM',       '12000-99', 'AL' FROM DUAL UNION ALL
SELECT 'Customer4', 42811, 'PSG550-L',  '40100-02', NULL FROM DUAL UNION ALL
SELECT 'Customer4', 42811, 'PSG550-M',  '40100-02', NULL FROM DUAL UNION ALL
SELECT 'Customer4', 42811, 'ADM',       '12000-99', 'GA' FROM DUAL UNION ALL
SELECT 'Customer5', 42812, 'GSS10-100', '40100-01', NULL FROM DUAL UNION ALL
SELECT 'Customer5', 42812, 'GSS10-350', '40100-05', NULL FROM DUAL UNION ALL
SELECT 'Customer5', 42812, 'GSD200',    '40100-01', NULL FROM DUAL UNION ALL
SELECT 'Customer5', 42812, 'ADM',       '12000-99', 'NC' FROM DUAL UNION ALL
SELECT 'Customer6', 42813, 'FSF105',    '40100-02', NULL FROM DUAL UNION ALL
SELECT 'Customer6', 42813, 'FSF135',    '40100-02', NULL FROM DUAL UNION ALL
SELECT 'Customer6', 42813, 'GSD310',    '40100-01', NULL FROM DUAL UNION ALL
SELECT 'Customer6', 42813, 'GSW311',    '40100-01', NULL FROM DUAL UNION ALL
SELECT 'Customer6', 42813, 'GSD190',    '40100-01', NULL FROM DUAL UNION ALL
SELECT 'Customer6', 42813, 'GSW312',    '40100-01', NULL FROM DUAL UNION ALL
SELECT 'Customer6', 42813, 'ADM',       '45100-99', NULL FROM DUAL UNION ALL
SELECT 'Customer6', 42813, 'ADM',       '12000-99', 'TX' FROM DUAL;

<强>更新

MERGE INTO invoices dst
USING ( SELECT MAX( SHIP_TO_STATE ) OVER ( PARTITION BY invoice_id )
                 AS new_ship_to_state
        FROM   invoices ) src
ON ( src.ROWID = dst.ROWID )
WHEN MATCHED THEN
UPDATE SET ship_to_state = src.new_ship_to_state;

<强>结果

SELECT * FROM invoices;

CUSTOMER_ INVOICE_ID ITEM_ID   GL_ACCOU SH
--------- ---------- --------- -------- --
Customer1      38441 ADM       46000-99 GA
Customer1      38441 ADM       12000-99 GA
Customer2      42809 GSD307    40100-02 WA
Customer2      42809 GSD310    40100-01 WA
Customer2      42809 GSW311    40100-01 WA
Customer2      42809 GSD200    40100-01 WA
Customer2      42809 FSR270    40100-02 WA
Customer2      42809 ADM       12000-99 WA
Customer3      42810 GSS10-100 40100-01 AL
Customer3      42810 GSS10-500 40100-05 AL
Customer3      42810 GSD210    40100-01 AL
Customer3      42810 ADM       45100-99 AL
Customer3      42810 ADM       12000-99 AL
Customer4      42811 PSG550-L  40100-02 GA
Customer4      42811 PSG550-M  40100-02 GA
Customer4      42811 ADM       12000-99 GA
Customer5      42812 GSS10-100 40100-01 NC
Customer5      42812 GSS10-350 40100-05 NC
Customer5      42812 GSD200    40100-01 NC
Customer5      42812 ADM       12000-99 NC
Customer6      42813 FSF105    40100-02 TX
Customer6      42813 FSF135    40100-02 TX
Customer6      42813 GSD310    40100-01 TX
Customer6      42813 GSW311    40100-01 TX
Customer6      42813 GSD190    40100-01 TX
Customer6      42813 GSW312    40100-01 TX
Customer6      42813 ADM       45100-99 TX
Customer6      42813 ADM       12000-99 TX

答案 3 :(得分:-1)

您正在使用相关子查询。您需要一个或多个表别名:

UPDATE INVOICES
    SET SHIP_TO_STATE = (SELECT i.SHIP_TO_STATE
                         FROM INVOICES i
                         WHERE i.GL_ACCOUNT_ID = '12000-99' AND
                               i.INVOICE_ID = INVOICES.INVOICE_ID
                        );

您是否应该将此信息存储在每个invoice_id有一行的表中?奇怪的是,这样的id将在名为INVOICES的表中重复。