我如何修改此代码以仅引入另一个表中不存在的值

时间:2015-08-11 06:15:05

标签: sql

我尝试使用下一个代码向用户介绍如何在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');

现在我观察到,这段代码引入了重复的值。

我的问题是:如何使此代码不引入重复值?

2 个答案:

答案 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 )