こんにちは、ねこです。

自称プログラマのおばちゃんのブログです。いろいろあるよねぇ~。

Microsoft MCSA SQL Server 2016 (70-761)むぼーな挑戦8/JOINのタイプ8個

2019-11-05 15:13:33 | プログラム 勉強

これは理解するために、そしてよく出る過去問題として、とぉ~ってもよい問題だったので頑張って平打ちすることにしました。(テストに丸々でるかもよぉ~!)

Customer_CSystem

Customer_HSystem

『You need to display customers who appear in both tables and have a non-null CustomerCode.』

A.

SELECT c.CustomerCode, c.CustomerName, h.CustomerCode, h.CustomerName
FROM Customer_CSystem c
INNER JOIN Customer_HSystem h
ON c.CustomerCode = h.CustomerCode AND c.CustomerName = h.CustomerName

両方のテーブルからマッチしている値を返すけど、もし重複しているものがあれば、それも全部返す。

B.
SELECT CustomerCode, CustomerName
FROM Customer_CSystem
INTERSECT
SELECT CustomerCOde, CustomerName
SROM Customer_HSystem

INNER JOINと同じだけど、『DISTINCT』を返します。だから、重複分はないよ。

C.
SELECT c.CustomerCode, c.CustomerName
FROM Customer_CSystem c
LEFT OUTER JOIN Customer_HSystem h
ON c.CUstomerCode = h.CustomerCode
WHERE h.CustomerCode IS NULL AND c.CustomerCode IS NOT NULL

ベーステーブルが左で(FROMのテーブル)、LEFT JOINされたテーブルはマッチしない場合に『NULL』と表示される。ここで大事なのは、ベーステーブルのすべての行が返ってきます。

D.
SELECT CustomerCode, CustomerName
FROM Customer_CSystem
EXCEPT
SELECT CustomerCode, CustomerName

『INTERSECT』と同じく『DISTINCT』を返します。だから、重複分はありません。しかし、『マッチしない』値が返ってきます。

E.
SELECT CustomerCOde, CustomerName
FROM Customer_CSystem
UNION
SELECT CustomerCode, CustomerName
FROM Customer_HSystem

そこかこのサイトで「UNIONは問合せの行をお互いに後に置くが、JOINはデカルト積を生成し、それを部分集合化する。まったく別の操作である。」と書いてあります。ようは、全てのマッチングを計算した後で『WHERE』でフィルターにかけるのがJOINだとしたら、UNIONだと二つ以上のテーブルを結合させてやることで、単体のテーブルとして結果を返します。そして、UNIONだけなら、重複データは返しません。

F.
SELECT CustomerCode, CustomerName
FROM Customer_CSystem
UNION ALL
SELECT CustomerCode, CustomerName
FROM Customer_HSystem

重複データをかえします。

G.
SELECT c.CustomerCOde, c.CustomerName, h.CustomerCode, h.CustomerName
FROM Customer_CSystem c
CROSS JOIN Customer_HSystem

これだけ、『ON』を使った条件は指定しません。これはもう、天文学的な数字になっちゃう可能性のある『すべてのマッチングパターン』です。『WHERE』文がない場合は十中八九ひっかけ問題でしょうね。

H.
SELECT c.CustomerCode, c.CustomerName, h.CustomerCode, h.CustomerName
FROM Customer_CSystem c
FULL OUTER JOIN Customer_HSystem h
ON c.CustomerCode = h.CustomerCode AND c.CustomerName = h.CustomerName

ベーステーブルと右テーブルのマッチする値全部とマッチしない値全部を返します。

 

はい、いつものように読み解きましょう。

You need to display customers who appear in both tables

ふむふむ、両方のテーブルにある『customers』を表示させればいいのか。

『and have a non-null CustomerCode』

それじゃ、『LEFT JOIN』以外のマッチングだな。『INNER JOIN』かな?『UNION』かな?それとも『INTERSECT』?

 

では、『A. INNER JOIN』はどうだろう。

『DISTINCT』がないから、重複データがとれちゃう。ぶっぶーっ!

では、『B. INTERSECT』はどうだろう。

『DISTINCT』なくても『INTERSECT』は勝手に重複データをはぶいてくれるよね。これかな?

では、『E. UNION』はどうだろう。

ううぉ~っ。。。悩む。だけど、フィルターないから、『NULL』データもユニークデータとしてでてきちゃうよね、きっと。だから違うかな?

 

...わからん。。。
【INTERSECTとJOINの違い】
1.INTERSECTは二つを比べて共通データを一つ抽出。NULLは、INTERSECTの演算子では「等しい」と見なされます。 また、SELECT文セットには、共通型の列が同数含まれている必要があります。
  1. INTERSECT just compares 2 sets and picks only distinct equivalent values from both sets. It's important to note that NULL marks are considered as equals in INTERSECT set operator. Also sets should contain equal number of columns with implicitly convertible types.

enter image description here

2.JOIN 両方のテーブルにNULLがある場合、SQLではNULL <> NULLであるため、それらの行は返されません

  1. If there are NULL marks in both tables those rows will not be returned because NULL <> NULL in SQL.
 
 
なんだってぇ~!じゃあ、答えはないの???
もう、これはやってみるしかない。
 
Create table Customer_CSystem(
CustomerID int not null,
CustomerCode char(4) null,
CustomerName varchar(50) not null
)
 
Create table Customer_HSystem(
CustomerID int not null,
CustomerCode char(4) null,
CustomerName varchar(50) not null
)
 
 
 
 
 
【UNION】
 
【INTERSET】
 
【JOIN】
 
実は途中で気が付いていた。
この『'Almudena'』の『CustomerID』がCSystemとHSystemで違うと。。。
(2, 'CUS9', 'Almudena')
(3, 'CUS9', 'Almudena')

そしてこのCustomerIDをフィルターしていないということで、ここにも大きな落とし穴があった。

しかし、知らぬが仏。どのステートメントにもこのフィルターはないから、出力結果に関係なし!

ただし、上記の「『DISTINCT』がないから、重複データがあるから無理」ってのは当てはまりませんでした。

もっとしっかりテーブルの値全部見なければなりませんね。

SELECT c.CustomerCode, c.CustomerName, h.CustomerCode, h.CustomerName 
FROM Customer_CSystem c
INNER JOIN Customer_HSystem h
ON c.CustomerCode = h.CustomerCode AND c.CustomerName = h.CustomerName

 
 
<答え>
A
どうやら、
両方のテーブルにNULLがある場合、SQLではNULL <> NULLであるため、それらの行は返されません。』というのが、実際の理由である。
 
ふぅ~疲れました。