假设我有一个名为 FRUITS 的表,如下所示:
身份证 | 产品 | 活跃 |
---|---|---|
1 | 苹果 | 1 |
1 | 橙色 | 1 |
2 | 橙色 | 0 |
(ID = 1 有两个产品,并且都有 ACTIVE = 1)。
现在我想要在同一个表中输出,如下所示:
身份证 | 产品 | 活跃 |
---|---|---|
1 | 苹果 | 1 |
1 | 橙色 | 1 |
2 | 橙色 | 1 |
2 | 苹果 | 1 |
所以我需要的是根据同一个表中的 PRODUCT 和 ID 的条件插入或更新表中的值。
或者换句话说 - 我想将现有 ID 中的所有列复制到具有相同产品(更新)的给定 ID 的行中,或者如果给定 ID 下不存在具有相同产品的行,则插入。
有没有一种方法可以通过单个语句来完成此操作,例如MERGE?
我尝试使用此 MERGE 语句,但它不起作用:
MERGE INTO fruits d
USING (SELECT id,
product,
active
FROM fruits
WHERE id = :old_id_in) s
ON (d.id = :new_id_in AND d.product = s.product)
WHEN MATCHED THEN
UPDATE SET d.product = s.product,
d.active = s.active
WHERE d.id = :new_id_in
WHEN NOT MATCHED THEN
INSERT (d.id, d.product, d.active)
VALUES(:new_id_in, s.product, s.active);
任何帮助表示赞赏!
您可以在
PARTITION
的 OUTER JOIN
子句中使用 USING
ed MERGE
:
MERGE INTO fruits dst
USING (
SELECT f.id,
a.product,
a.active
FROM ( SELECT product,
MAX(active) AS active
FROM fruits
GROUP BY product
) a
LEFT OUTER JOIN fruits f
PARTITION BY (f.id)
ON (a.product = f.product)
) src
ON (dst.id = src.id AND dst.product = src.product)
WHEN MATCHED THEN
UPDATE
SET active = src.active
WHEN NOT MATCHED THEN
INSERT (id, product, active)
VALUES(src.id, src.product, src.active);
对于样本数据:
CREATE TABLE fruits (ID, PRODUCT, ACTIVE) AS
SELECT 1, 'apple', 1 FROM DUAL UNION ALL
SELECT 1, 'orange', 1 FROM DUAL UNION ALL
SELECT 2, 'orange', 0 FROM DUAL UNION ALL
SELECT 3, 'pear', 0 FROM DUAL;
然后,在
MERGE
之后,表格包含:
SELECT * FROM fruits ORDER BY id, product
身份证 | 产品 | 活跃 |
---|---|---|
1 | 苹果 | 1 |
1 | 橙色 | 1 |
1 | 梨子 | 0 |
2 | 苹果 | 1 |
2 | 橙色 | 1 |
2 | 梨子 | 0 |
3 | 苹果 | 1 |
3 | 橙色 | 1 |
3 | 梨子 | 0 |