SQLServer2017を使って内部結合と外部結合の違いをどこよりもわかりやすく解説!6

当サイトではアフィリエイト広告を利用しています。

SQLServer初心者

前回まででSQLServerをインストールして基本的なSQLを学び,正規化のやり方とテーブル設計を行い実際にテーブルの実装までを行いました。ただ正規化されたテーブルは必要な情報が2つ以上のテーブルに分かれて入っていることがよくあるため結合という処理で1つのテーブルにまとめる必要があります。

今回はその結合の中で初心者にはわかりずらい「内部結合」と「外部結合」の違いをどこよりもわかりやすく解説します。

SELECT文を書いてみる(単純に全件)

「新しいクエリ」からSELECT文を実行してみましょう。

3行まとめて実行しています。手で入力した通りのデータが格納されているのが確認できます。

SELECT文を書いてみる(内部結合)

それではすこし難しくなりますが,結合という話をします。結合とは,2つ以上のテーブルをくっつけることです。くっつけ方は,ふつうはキーを元に結合します。「注文テーブル」と「注文明細テーブル」を1つに結合する場合は,「注文No」で一致させて,合体させると顧客が購入した一回分の注文データとなります。

SQLはこんな感じになります。

select  A.OrderNo,

       A.OrderDate,

   A.UserId,

       B.OrderItemNo,

  B.ProductName,

  B.Price

from Orders A

inner join OrderItems B

on A.OrderNo = B.OrderNo
  1. SELECTのあとはカンマ区切りで取得したい項目名を書きます
  2. fromの後はテーブル名を書きますが,
    
    これは結合するときのメインとなるテーブルとします。
    
    今回は注文テーブルとなります。
  3. inner join の後に2つ目のテーブルを書きます。
    
    今回は「注文明細テーブル」となります。
  4. on の後に「注文」と「注文明細」を一致させる条件を書きます。
    
    今回は「注文No」になります。
  5. Ordersの後の「A」とOrderItemsの後の
    
    「B」は別名といって,
    
    どちらのテーブルの項目化を示すときに
    
    OrderNoとしなくても,
    
    A.OrderNoと省略して書くために書いています。

「inner join」は内部結合といって,「両方のテーブルに存在する場合のみデータを取得する」という意味になります。

これで,注文と注文明細が結合されて結果に表示されます。

SELECT文を書いてみる(外部結合)

先ほどのSQLだと「UserId」が表示されていますが,これでは顧客の名称がわかりません。アプリケーションなどで表示する場合は,必ず名称も必要になります。そこで,顧客テーブルも結合します。今回は外部結合を使ってみます。

select A.OrderNo,
   A.OrderDate,
   A.UserId,
   C.UserName,
   B.OrderItemNo,
   B.ProductName,
   B.Price
from Orders A
inner join OrderItems B
on A.OrderNo = B.OrderNo
left outer join UserAccount C
on A.UserId = C.UserId

今回はSELECT句の「C.UserName,」と最後に2行を増やしました。left outer join は外部結合というもので,処理としては要するに「結合はするけど一致しない場合はNULLでいいよ」という動きになります。解説はのちほどするとして,一度どのような結果になるか確認しましょう。

先ほどと同じように9行出力されています。UserIdの横にはUserNameが表示されています。これならどの顧客か,目で見てわかるようになります。さて内部結合と外部結合の違いですが,例えばOrdersテーブルの1行目のUserIdを「999」に変えてみましょう。

この状態でもう一度先ほどの外部結合のSQLを実行します。

OrderNo「1」の2行はUserNameがNullになっていますね。

理由はUserId「999」が存在しないからですが,外部結合はこのようになければNullを返すというくっつき方をするので全体の9行は変わりません。一方,内部結合は両方のテーブルにないと行を返さないので,内部結合にすると1行目と2行目は取得されずに,全体は7行になります。実際にやってみましょう。

select A.OrderNo,
       A.OrderDate,
       A.UserId,
       C.UserName,
       B.OrderItemNo,
       B.ProductName,
       B.Price
from Orders A
inner join OrderItems B
on A.OrderNo = B.OrderNo
inner join UserAccount C
on A.UserId = C.UserId

※left outer join をinner join に変更しています。

OrderNo「1」の行が取得されずに結果は7行となりました。内部結合と外部結合の部分は,最初はわかりにくいので色々なデータで確認してみてください。

並べ替えのOrder by を書いてみる(ASC,DISC)

それでは最後に並べ替えのやり方を見ていきましょう。SELECT結果を並べ替える場合はOrder byというのを使います。Order by の後に項目名を書くとその項目順になります。例えば日付順にする場合は order by OrderDateとなります。書く場所はSQLの一番最後の行になります。

OrderDateの順番に並び変わりました。昇順ではなく降順に並び替える場合は,項目名の後にDescと書きます

これで大きい値順(降順)で並び変わりました。order by は複数項目を指定することもできます。複数の場合は日付の古い順,その中で金額が多い順などという並び替えになります。