我有3个表A
,B
,C
所有3个表的模式与下面提到的相同:
id, time1, place, xyz, abc, pqrs
现在,两个表A
和B
都有很多记录(大约1000万)
现在,A和B中的某些记录具有相同的id
,有些记录具有不同的Id
现在,我想将A
和B
的记录合并到表格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查询,使用A
和B
之间的外部联接。但我不太清楚如何去做。
答案 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.,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
*/