我有这些表格:
Table A
Num Letter
1 A
2 B
3 C
Table B
Num Letter
2 C
3 D
4 E
我想结合这两个表,但我只希望每个数字出现一次。如果两个表中都出现相同的数字,我希望它来自表B而不是表A.
Result
Num Letter
1 A
2 C
3 D
4 E
我怎么能做到这一点?联合将保留重复,并且交叉将仅捕获相同的行 - 当具有相同的数字时,我认为该行是重复的,无论该字母是什么。
答案 0 :(得分:1)
试试这个:http://www.sqlfiddle.com/#!4/0b796/1
with a as
(
select Num, 'A' as src, Letter
from tblA
union
select Num, 'B' as src, Letter
from tblB
)
select
Num
,case when count(*) > 1 then
min(case when src = 'B' then Letter end)
else
min(Letter)
end as Letter
from a
group by Num
order by Num;
输出:
| NUM | LETTER |
----------------
| 1 | A |
| 2 | C |
| 3 | D |
| 4 | E |
答案 1 :(得分:1)
还有一个:
SELECT COALESCE(b.num, a.num) num, COALESCE(b.letter, a.letter) letter
FROM a FULL JOIN b ON a.num = b.num
ORDER BY 1;
使用您的数据:
WITH a AS
(SELECT 1 num, 'A' letter FROM dual
UNION ALL SELECT 2, 'B' FROM dual
UNION ALL SELECT 3, 'C' FROM dual),
b AS
(SELECT 2 num, 'C' letter FROM dual
UNION ALL SELECT 3, 'D' FROM dual
UNION ALL SELECT 4, 'E' FROM dual)
SELECT COALESCE(b.num, a.num) num, COALESCE(b.letter, a.letter) letter
FROM a FULL JOIN b ON a.num = b.num
ORDER BY 1;
NUM L
---------- -
1 A
2 C
3 D
4 E
答案 2 :(得分:0)
可能缺乏效率,但它会产生正确的答案。
select nums.num, coalesce(b.letter, a.letter)
from
(select num from b
union
select num from a) nums
left outer join b
on (b.num = nums.num)
left outer join a
on (a.num = nums.num);
答案 3 :(得分:0)
或者您可以使用特定于Oracle的技术来缩短代码:http://www.sqlfiddle.com/#!4/0b796/11
with a as
(
select Num, 'A' as src, Letter
from tblA
union
select Num, 'B' as src, Letter
from tblB
)
select Num, min(Letter) keep(dense_rank first order by src desc) as Letter
from a
group by Num
order by Num;
输出:
| NUM | LETTER |
----------------
| 1 | A |
| 2 | C |
| 3 | D |
| 4 | E |
代码无论min(letter)
还是max(letter)
都有效,它具有相同的输出,它提供相同的输出。重要的是你使用keep dense_rank
。另一个重要的事情是,订单很重要,我们使用order by src desc
在保留一行时优先考虑源表B.
要真正缩短内容,请使用keep dense_rank last
,并按顺序省略desc
,asc
无论如何都是默认http://www.sqlfiddle.com/#!4/0b796/12
with a as
(
select Num, 'A' as src, Letter
from tblA
union
select Num, 'B' as src, Letter
from tblB
)
select Num, min(Letter) keep(dense_rank last order by src) as Letter
from a
group by Num
order by Num;
再一次,在Letter上使用min
或max
并不重要,只要你保持dense_rank获得优先级/首选行
答案 4 :(得分:0)
另一种选择是将UNION和MINUS命令组合如下:
SELECT
NUM, LETTER
FROM
TABLE B
UNION
( SELECT
NUM, LETTER
FROM
TABLE A
WHERE
NUM IN (SELECT
NUM
FROM
TABLE A
MINUS
SELECT
NUM
FROM
TABLE B ))
答案 5 :(得分:0)
SELECT A.*
FROM A
WHERE A.NUM NOT IN
(SELECT A.NUM
FROM B
WHERE A.NUM=B.NUM
AND B.NUM IS NOT NULL
AND A.NUM IS NOT NULL
)
UNION
SELECT * FROM B;