1

私はこれらのテーブルを持っています:

Table A
Num Letter 
1   A      
2   B      
3   C     

Table B
Num Letter
2   C      
3   D   
4   E 

これら 2 つのテーブルを結合したいのですが、各数値を 1 回だけ表示したいのです。両方のテーブルに同じ数字が表示されている場合は、テーブル A ではなくテーブル B から取得します。

Result
Num Letter
1   A
2   C
3   D
4   E

どうすればこれを達成できますか? ユニオンは重複を保持し、交差は同じ行のみをキャッチします-文字に関係なく、同じ番号を持つ行を重複と見なします。

4

6 に答える 6

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
于 2012-06-16T00:46:49.123 に答える
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 |
于 2012-06-15T23:54:09.283 に答える
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です。もう1つの重要なことは、順序の問題order by src descです。行を保持するときにソーステーブルBを優先するために使用します。


そして、実際に短くするには、を使用し、注文時keep dense_rank lastを省略します。とにかくデフォルトですhttp://www.sqlfiddle.com/#!4/0b796/12descasc

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を使用するminmax、Letterを使用するかは重要ではありません。ただし、keepdensity_rankが優先/優先行を取得する限りです。

于 2012-06-16T00:27:22.683 に答える
0

もう 1 つのオプションは、次のように 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 ))
于 2012-06-16T00:33:48.963 に答える
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;
于 2012-06-16T07:20:29.640 に答える
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);
于 2012-06-15T23:41:42.743 に答える