SQL中的全外連線

2021-04-18 04:14:37 字數 2638 閱讀 8514

今天看到一貼, 說到 mysql 不支援全外連線, 希望能給出乙個方法能夠解決這個問題.

我們首先必須明白在數學領域, set 和 bag 是兩種不同的概念. bag 比 set 更加複雜. 主要就是允許了元素的重複出現. 因此 bag 的union, intersect, difference 也就有了些區別.

要模擬全外連線, 我們需要借助: 左外連線(右外連線是左外連線的對稱運算...), union all, except all.

為什麼要用 union all, except all? 因為 join 操作產生的結果集是 bag, 因此必須使用 bag 運算子.

我沒有花太多時間設計測試用例, 這裡只是簡單的給出幾個錯誤的結果, 希望大家平時應用小心.

sql server 2005 雖然支援全外連線, 但是不支援 except all, 因此無法模擬這個過程. 需要注意使用混合使用 bag 和 set 的運算子將會對結果產生影響. 除非你清楚你的目的, 否則永遠不要把它們混合在一起.

下面是測試用例的準備:

create table a(c int);

create table b(c int);

insert into a values(1);

insert into a values(2);

insert into a values(3);

insert into b values(1);

insert into b values(1);

insert into b values(2);

insert into b values(4);

下面是在sql server 2005中執行的標準輸出結果(5條!):
select * from a full join b on a.c = b.c;

c           c

----------- -----------

1           1

1           1

2           2

3           null

null        4

(5 row(s) affected)

我們看到了兩行(1,1), 這就是我們需要注意的 bag 才具有的行為. 下面是幾個典型的錯誤語句:
select * from a left join b on a.c = b.c union select * from a right join b on a.c = b.c;
c           c

----------- -----------

null        4

1           1

2           2

3           null

(4 row(s) affected)

select * from a left join b on a.c = b.c union all select * from a right join b on a.c = b.c;
c           c

----------- -----------

1           1

1           1

2           2

3           null

1           1

1           1

2           2

null        4

(8 row(s) affected)

select a.c, b.c from a left join b on a.c = b.c

union

select a.c, b.c from b left join a on a.c = b.c

where a.c is null;

c           c

----------- -----------

null        4

1           1

2           2

3           null

(4 row(s) affected)

正確的應該是:
select * from a left join b on a.c = b.c union all select * from a right join b on a.c = b.c except all select * from a inner join b on a.c = b.c;
希望大家小心 bag 和 set 的區別. 你還可以指定 distinct 消除重複元組. 但是你必須清楚這些操作的影響, 有人說 bag 操作是 sql 語言最大的缺點... 我倒覺得仁者見仁, 智者見智. 就好像有人說 '第一正規化' 關於不應該有 null 值的問題, 認為既然最初允許了 null 為什麼第一正規化就要禁止呢?
最後大家要注意 wikipedia 上關於 join 的說明並沒有考慮 bag 的情況, 而是當作 set 給出的例子. 希望不是 wikipedia 的錯誤, 端午過後, 我再去仔細求證一下.

sql連線(內連線 外連線 全連線)

現有table for report 1和table for report 2,詳情如下 table for report 1有num欄位,c1,c2,c3欄位。資料如下 num c1 c2 c3 1 15001346690 11 12 13 2 13329921100 21 22 23 3 189...

SQL 左外連線,右外連線,全連線,內連線

例子1 a表 id name b表 id job parent id 1 張3 1 23 1 2 李四 2 34 2 3 王武 3 34 4 a.id同parent id 存在 關係內連線 select a.b.from a inner join b on a.id b.parent id 結果是 ...

SQL之全外連線,左外連線,右外連線,內連線

1.內連線 內聯接使用比較運算子 使用像 或 之類的比較運算子 根據每個表共有的列的值匹配兩個表中的行,根據這兩張表中相同列的條件,得出其交集。沒有inner join,形成的中間表為兩個表的笛卡爾積 select from customers c,orders o where c.id o.cus...