如何从Oracle 10中的两个表连接结果

时间:2009-10-13 12:50:15

标签: sql oracle join

假设我有2个具有相同结构的表:STOCKNEW_STOCK。 这些表的主键由(ID_DATE,ID_SELLER,ID_INVOICE,ID_DOC)​​组成。

现在,我需要为每个(ID_DATE,ID_SELLER,ID_INVOICE,ID_DOC)​​获取有关此要求的金额(字段AMOUNT):

如果NEW_STOCK中有记录,我会从NEW_STOCK获得AMOUNT,否则,我会从STOCK表中获得AMOUNT。

请注意,ID_DATE和ID_SELLER是给查询的输入,即仅考虑STOCK表的查询将如下所示:

select AMOUNT, ID_DATE, ID_SELLER, ID_INVOICE
    from STOCK
    where ID_DATE = 1
      and ID_SELLER = 'SELL1';

STOCK

+---------+-----------+------------+--------+--------+
| ID_DATE | ID_SELLER | ID_INVOICE | ID_DOC | AMOUNT |
+---------+-----------+------------+--------+--------+
|       1 |     SELL1 |        IN1 |   DOC1 |    100 |
|       1 |     SELL1 |        IN2 |   DOC2 |     50 |
|       1 |     SELL1 |        IN3 |   DOC3 |     42 |
+---------+-----------+------------+--------+--------+

NEW_STOCK

+---------+-----------+------------+--------+--------+
| ID_DATE | ID_SELLER | ID_INVOICE | ID_DOC | AMOUNT |
+---------+-----------+------------+--------+--------+
|       1 |     SELL1 |        IN2 |   DOC2 |     12 |
+---------+-----------+------------+--------+--------+

然后,我必须得到以下结果:

+---------+-----------+------------+--------+--------+
| ID_DATE | ID_SELLER | ID_INVOICE | ID_DOC | AMOUNT |
+---------+-----------+------------+--------+--------+
|       1 |     SELL1 |        IN1 |   DOC1 |    100 |
|       1 |     SELL2 |        IN2 |   DOC2 |     12 |
|       1 |     SELL3 |        IN3 |   DOC3 |     42 |
+---------+-----------+------------+--------+--------+

ps:我正在研究Oracle 10。

4 个答案:

答案 0 :(得分:3)

使用外连接和NVL(arg1,arg2)功能。 如果它不是NULL,则返回第一个参数,否则返回第二个参数。例如:

select s.AMOUNT, s.ID_DATE, s.ID_SELLER, s.ID_INVOICE,
   NVL(n.AMOUNT, s.AMOUNT) amount       
from STOCK s, NEW_STOCK n
where s.ID_DATE = n.ID_DATE(+) 
  and s.ID_SELLER = n.ID_SELLER(+)
  and s.ID_INVOICE = n.ID_INVOICE(+)
  and s.ID_DOC = n.ID_DOC(+)
  and s.ID_DATE = 1
  and s.ID_SELLER = 'SELL1';

如果您发现它更具可读性,则可以使用LEFT OUTER JOIN语法而不是(+)。我从v7开始使用Oracle,我更喜欢(+)

这是LEFT OUTER JOIN语法:

select s.AMOUNT, s.ID_DATE, s.ID_SELLER, s.ID_INVOICE,
   NVL(n.AMOUNT, s.AMOUNT) amount       
from  STOCK s left outer join NEW_STOCK n 
      on s.ID_DATE = n.ID_DATE
         and s.ID_SELLER = n.ID_SELLER
         and s.ID_INVOICE = n.ID_INVOICE
         and s.ID_DOC = n.ID_DOC
where s.ID_DATE = 1
  and s.ID_SELLER = 'SELL1';

答案 1 :(得分:0)

SELECT * FROM (
    SELECT * FROM new_stock
    UNION ALL
    SELECT * FROM stock
    WHERE (ID_DATE,ID_SELLER,ID_INVOICE,ID_DOC) NOT IN 
     (SELECT ID_DATE,ID_SELLER,ID_INVOICE,ID_DOC FROM new_stock)
)
WHERE ID_DATE = 1 
   AND ID_SELLER = 'SELL1';

答案 2 :(得分:0)

以下内容适用于此:

SELECT s.AMOUNT, s.ID_DATE, s.ID_SELLER, s.ID_INVOICE    
FROM STOCK s
LEFT JOIN NEW_STOCK ns 
   ON s.ID_DATE = ns.ID_DATE 
   AND s.ID_SELLER = ns.ID_SELLER 
   AND s.ID_INVOICE = ns.ID_INVOICE
WHERE s.ID_DATE = 1      
  AND s.ID_SELLER = 'SELL1'
  AND ns.ID_DATE IS NULL
UNION
SELECT AMOUNT, ID_DATE, ID_SELLER, ID_INVOICE    
FROM NEW_STOCK    
WHERE ID_DATE = 1
  AND ID_SELLER = 'SELL1';

从使用NEW_STOCK表的结果设置的LEFT JOIN和UNION中排除匹配的行。

答案 3 :(得分:0)

SELECT COALESCE(NS.AMOUNT, S.AMOUNT) AMOUNT, 
       S.ID_DATE, 
       S.ID_SELLER, 
       S.ID_INVOICE
  FROM STOCK S 
  LEFT JOIN NEW_STOCK NS ON S.ID_DATE = NS.ID_DATE
                        AND S.ID_SELLER = NS.ID_SELLER
                        AND S.ID_INVOICE = NS.ID_INVOICE
                        AND S.ID_DOC = NS.ID_DOC 
 WHERE S.ID_DATE = 1
   AND S.ID_SELLER = 'SELL1'