假设我有2个具有相同结构的表:STOCK
和NEW_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。
答案 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'