我尝试使用下一个代码向用户介绍如何在glob表中,但它们不存在于tlp表中,但每次运行程序时,都会为一个用户引入重复值。我不明白为什么。
INSERT INTO tlp
(given_name,
namel,
email, poreclat)
SELECT first_name,
namel,
mail, porecla
FROM glob
WHERE
(( NOT EXISTS (SELECT email
FROM tlp
WHERE glob.mail = tlp.email )
AND glob.mail IS NOT NULl)
and glob.country='Romania'
)
or (( NOT EXISTS (SELECT namel
FROM tlp
WHERE glob.namel = tlp.namel
)
and glob.country='Romania'))
or ( exists (select given_name
from tlp
where (glob.first_name not like '07_%') and
glob.first_name not like 'car%' and
glob.first_name not like 'TR_%'
)
);
这里我创建了表格
create table glob
( persone_id number not null ENABLE,
first_name varchar(10),
namel varchar(10),
mail varchar(50),
country varchar(10),
porecla varchar (10),
create_date date default sysdate);
insert into glob(persone_id,first_name, namel, mail) values (1, 'daniela', 'pop', 'dany_pop93@yahoo.com');
insert into glob(persone_id,first_name, namel,mail, country) values (2, 'razvan', 'cirstescu', null, 'Romania');
insert into glob (persone_id,first_name, namel, country) values (3, 'darius', 'moldovan', 'Germany' );
insert into glob (persone_id,first_name, namel, mail, country) values (4, 'alex', 'duta', null, 'Romania');
insert into glob(persone_id,first_name, namel, mail, country) values (5, 'edith', null, 'edith@yahoo', 'Romania');
insert into glob(persone_id,first_name, namel, mail) values (6, 'madi', 'todea', 'madi@yahoo');
insert into glob(persone_id,first_name, namel, mail) values (7, 'madi', 'todea', 'madi@yahoo');
insert into glob(persone_id,first_name, namel, mail) values (8, 'madi', 'todea', 'madi@yahoo');
第二个表是:
create table tlp
( given_name varchar(10),
namel varchar (10),
email varchar (50),
poreclat varchar(10),
create_date date default sysdate);
insert into TLP(given_name, namel, email) values ('daniela', 'pop', 'dany_pop93@yahoo.com');
insert into TLP(given_name, namel, email) values ('andrei', 'pop', 'andrei@yahoo');
现在我观察到,这段代码引入了重复的值。
我的问题是:如何使此代码不引入重复值?
答案 0 :(得分:1)
首先,您应该创建一个唯一约束,以避免插入任何重复行。
SQL> ALTER TABLE tlp ADD CONSTRAINT tlp_unq UNIQUE (given_name, namel, email, poreclat, create_date);
Table altered.
使用 MERGE 进行upsert,很容易理解并且非常详细。唯一要记住的是使用 DISTINCT 从glob
表中选择不同的行。问题是您的源表 glob
中已经有重复行。
SQL> MERGE INTO tlp d
2 USING (SELECT DISTINCT first_name, namel, mail, porecla, create_date FROM glob) s
3 ON(d.given_name = s.first_name) -- join key(s)
4 WHEN MATCHED THEN
5 UPDATE SET d.namel = s.namel,
6 d.email = s.mail,
7 d.poreclat = s.porecla,
8 d.create_date = s.create_date
9 WHEN NOT MATCHED THEN
10 INSERT (given_name,
11 namel,
12 email, poreclat, create_date)
13 VALUES (s.first_name,
14 s.namel,
15 s.mail, s.porecla, s.create_date );
6 rows merged.
让我们验证表格:
SQL> SELECT * FROM tlp;
GIVEN_NAME NAMEL EMAIL PORECLAT CREATE_DATE
---------- ---------- -------------------- ---------- -----------
alex duta 11-AUG-15
madi todea madi@yahoo 11-AUG-15
edith edith@yahoo 11-AUG-15
darius moldovan 11-AUG-15
razvan cirstescu 11-AUG-15
daniela pop dany_pop93@yahoo.com 11-AUG-15
andrei pop andrei@yahoo 11-AUG-15
7 rows selected.
SQL>
更新 OP希望知道如何过滤行,即使用WHERE子句 条件INSERTS和UPDATES。
您可以简单地将WHERE子句添加到update和insert语句中:
例如
MERGE INTO test1 a
USING all_objects b
ON (a.object_id = b.object_id)
WHEN MATCHED THEN
UPDATE SET a.status = b.status
WHERE b.status != 'VALID'
WHEN NOT MATCHED THEN
INSERT (object_id, status)
VALUES (b.object_id, b.status)
WHERE b.status != 'VALID';
查看更多示例here。
答案 1 :(得分:0)
尝试使用distinct +更新条件
INSERT INTO tlp
(given_name,
namel,
email, poreclat)
SELECT DISTINCT first_name,
namel,
mail, porecla
FROM glob
(( NOT EXISTS (SELECT email
FROM tlp
WHERE glob.mail = tlp.email )
AND glob.mail IS NOT NULl)
and glob.country='Romania'
)
or (( NOT EXISTS (SELECT namel
FROM tlp
WHERE glob.namel = tlp.namel
)
and glob.country='Romania'))
or ( exists (select given_name
from tlp
where (glob.first_name not like '07_%') and
glob.first_name not like 'car%' and
glob.first_name not like 'TR_%'
)
)
and (first_name, namel, mail, porecla) not in (select given_name, namel, email, poreclat from tlp )