使用SQL将两个表中的记录合并到第三个表中

时间:2013-08-16 16:12:50

标签: sql oracle

我有3个表ABC

所有3个表的模式与下面提到的相同:

id, time1, place, xyz, abc, pqrs  

现在,两个表AB都有很多记录(大约1000万)

现在,A和B中的某些记录具有相同的id,有些记录具有不同的Id

现在,我想将AB的记录合并到表格C中。合并逻辑如下

1)If records with id = someId is present only in A or B ( only in one table)
    then insert record from that table (A/B depending of where its present) in table C
2)If records with id =someId is present in both A and B {

           if(A.time1 > B.time2){
             insert record from A into C
          }else{
             insert record from B into C
          }
    }

我希望使用单个SQL查询,使用AB之间的外部联接。但我不太清楚如何去做。

5 个答案:

答案 0 :(得分:2)

假设表C为空,那么像这样的东西就可以了解

INSERT INTO C           
SELECT A.* 
  FROM A LEFT OUTER JOIN B
  ON A.ID = B.ID
 WHERE (A.TIME1 > B.TIME1 OR B.TIME1 IS NULL)
UNION 
SELECT B.*
  FROM B LEFT OUTER JOIN A
  ON B.ID = A.ID
 WHERE (A.TIME1 <= B.TIME1 OR A.ID IS NULL)

答案 1 :(得分:1)

使用UNION,你可以尝试这样的事情:

INSERT INTO C
SELECT A.* 
FROM A 
LEFT OUTER JOIN B ON A.ID = B.ID 
WHERE A.TIME1 > B.TIME1 OR B.ID IS NULL
UNION 
SELECT B.*
FROM B 
LEFT OUTER JOIN A ON B.ID = A.ID 
WHERE B.TIME1 > A.TIME1 OR A.ID IS NULL

SQLFIDDLE:http://www.sqlfiddle.com/#!4/5019b/2/0

答案 2 :(得分:0)

结合3个结果集:

  1. 包含共享ID的记录。
  2. 仅包含ID的记录
  3. 仅包含ids
  4. 的ID的记录

    1.,2。可以组合成1个左连接,3。是针对唯一ID发生的右连接过滤。选择a作为数据源2.,b表示3.,a / b取决于1的优先级。选择逻辑可以压缩到单个条件,因为time1比较只会产生一个布尔值,如果没有为空,即。来自1的记录。

        insert 
          into c ( id, time1, place, xyz, abc, pqrs )
             (
                select id1
                     , time1
                     , place
                     , xyz
                     , abc
                     , pqrs
                  from (
                            select a1.id    id1
                                 , b1.id    id2
                                 , CASE b1.time1 > a1.time1 then b1.time1   else a1.time1   end time1
                                 , CASE b1.time1 > a1.time1 then b1.place   else a1.place   end place
                                 , CASE b1.time1 > a1.time1 then b1.xyz     else a1.xyz     end xyz
                                 , CASE b1.time1 > a1.time1 then b1.abc     else a1.abc     end abc
                                 , CASE b1.time1 > a1.time1 then b1.pqrs    else a1.pqrs    end pqrs
                              from a a1
                         left join b b1 on ( b1.id = a1.id )
                             union
                            select b2.id    id1
                                 , a2.id    id2
                                 , b2.time1
                                 , b2.xyz
                                 , b2.place
                                 , b2.abc  
                                 , b2.pqrs                                      , 
                              from b b2
                         left join a a2 on ( a2.id = b2.id )
                             where a2.id is null
                       ) pairs
             )
             ;
    

答案 3 :(得分:0)

在一个请求中:

insert into C
  -- Outer join on B: if B is null null or A has greater time take A
  select case when B.id is null or A.time1 > B.time1 then A.id else B.id end,
         case when B.id is null or A.time1 > B.time1 then A.time1 else B.time1 end,
         case when B.id is null or A.time1 > B.time1 then A.place else B.place end,
         case when B.id is null or A.time1 > B.time1 then A.xyz else B.xyz end,
         case when B.id is null or A.time1 > B.time1 then A.abc else B.abc end,
         case when B.id is null or A.time1 > B.time1 then A.pqrs else B.pqrs end
  from A, B
  where B.id (+) = A.id
union all
  -- Then get the ones in B and not in A with outer join on A
  select B.id, B.time1, B.place, B.xyz, B.abc, B.pqrs
  from B, A
  where A.id (+) = B.id
    and A.is is null

答案 4 :(得分:0)

CREATE TABLE t_c
(
    id_c   NUMBER
,   time_c DATE
);

INSERT
WHEN    id_a IS NULL THEN INTO t_c(id_c, time_c) VALUES (id_b, time_b)
WHEN    id_b IS NULL THEN INTO t_c(id_c, time_c) VALUES (id_a, time_a)
WHEN    id_a = id_b AND time_a >  time_b THEN INTO t_c(id_c, time_c) VALUES (id_a, time_a)
WHEN    id_a = id_b AND time_a <= time_b THEN INTO t_c(id_c, time_c) VALUES (id_b, time_b)
SELECT  *
FROM
(
        SELECT  1 id_a, DATE'2013-01-01' time_a FROM dual UNION ALL
        SELECT  2 id_a, DATE'2013-01-02' time_a FROM dual UNION ALL
        SELECT  3 id_a, DATE'2013-01-03' time_a FROM dual UNION ALL
        SELECT  4 id_a, DATE'2013-01-04' time_a FROM dual UNION ALL
        SELECT  7 id_a, DATE'2013-01-07' time_a FROM dual UNION ALL
        SELECT  8 id_a, DATE'2013-01-08' time_a FROM dual
) t_a
FULL    JOIN
(
        SELECT  1 id_b, DATE'2013-01-01' time_b FROM dual UNION ALL
        SELECT  2 id_b, DATE'2013-01-02' time_b FROM dual UNION ALL
        SELECT  5 id_b, DATE'2013-01-05' time_b FROM dual UNION ALL
        SELECT  6 id_b, DATE'2013-01-06' time_b FROM dual UNION ALL
        SELECT  7 id_a, DATE'2013-01-09' time_a FROM dual UNION ALL
        SELECT  8 id_a, DATE'2013-01-01' time_a FROM dual
) t_b
ON      t_a.id_a = t_b.id_b
;
/*
1   2013-01-01 00:00:00     1   2013-01-01 00:00:00
2   2013-01-02 00:00:00     2   2013-01-02 00:00:00
                            5   2013-01-05 00:00:00
                            6   2013-01-06 00:00:00
7   2013-01-07 00:00:00     7   2013-01-09 00:00:00
8   2013-01-08 00:00:00     8   2013-01-01 00:00:00
4   2013-01-04 00:00:00     
3   2013-01-03 00:00:00     
*/

SELECT  *
FROM    t_c;
/*
5   2013-01-05 00:00:00
6   2013-01-06 00:00:00
4   2013-01-04 00:00:00
3   2013-01-03 00:00:00
8   2013-01-08 00:00:00
1   2013-01-01 00:00:00
2   2013-01-02 00:00:00
7   2013-01-09 00:00:00
*/