リラックス結合演算子は次のように定義されます。
関係RとSの自然結合が空でない場合は、この結合の結果を返します。それ以外の場合は、RとSのデカルト積を返します。
問題は、2つの関係のrelax-joinを返すが、IF-THEN-ELSEを使用しない関係代数とSQLを作成することです。
リラックス結合演算子は次のように定義されます。
関係RとSの自然結合が空でない場合は、この結合の結果を返します。それ以外の場合は、RとSのデカルト積を返します。
問題は、2つの関係のrelax-joinを返すが、IF-THEN-ELSEを使用しない関係代数とSQLを作成することです。
これは宿題としてタグ付けされているので、私はガイダンスを提供するだけだと思います.
考慮すべき点は次のとおりです。
ユニオンを使用すると、2 つのクエリ A と B の結果を組み合わせることができます。A、B、または両方にレコードが含まれているかどうかは関係ありません。
クロス結合と自然結合は、同じ結果列を生成します。UPDATE @ypercubeが指摘したように、これは真実ではありません。MYSQL
同じ列を返すようにSQLを記述して、ユニオンで両方を使用できるようにすることができます。これはうまくいくかもしれませんし、うまくいかないかもしれません。
シナリオを考えると、レコードを返す場合、クロス結合は常にレコードを生成します。自然結合は、場合によってはそうでない場合もあります。
あまりにも多くのヒントではないことを願っています. あなたがそれを理解したら私たちに知らせてください!
アップデート
x時間後に実際の回答を投稿することになっていたことに気づきませんでしたが、ここに私が示唆していた疑似クエリがあります:
SELECT *
FROM R
CROSS JOIN S
WHERE NOT EXISTS (
SELECT *
FROM R
NATURAL JOIN S
)
UNION
SELECT *
FROM R
NATURAL JOIN S
これはリレーションを含む演算子であるため、SQL で可能な限り、結果もリレーションである必要があると想定できます。つまり、重複列、重複行、NULL などではありません。関係R
でありS
、一般的である場合、それらの自然な結合はそれらの積と同じ結果をもたらします。
すでに指摘したように、R
とS
がいくつかの共通の属性 (同じ名前、同じ型) を持っている場合、SQL ではテーブルの積によって重複する列が生成されます。をクエリするという考えを無視してINFORMATION_SCHEMA
、リラックス結合を SQL で一般化することはできません。代わりに、明示的なプロジェクション、つまりSELECT
明示的な属性を持つ句を使用する必要があります。少なくともその一部は「ドット修飾」する必要があります。たとえばR { x, y }
、共通S { y, z }
のy
列がある場合、製品は次のように表現できます。
SELECT DISTINCT R.x, R.y, S.z
FROM R CROSS JOIN S
つまり、 のすべての属性の射影と、共通ではないことが知られてR
いる の属性です。S
同じ結果が得られる可能性は他にも多数ありますが、いずれも関連する属性についての事前知識を必要とします。
射影が明示的でなければならないことを受け入れたので、自然結合を theta 結合と同等のものとして表現しても、つまり次[INNER] JOIN
のON
節を使用しても何も失われません。
SELECT DISTINCT R.x, R.y, S.z
FROM R JOIN S ON R.y = S.y
CORRESPONDING
同様に、SQL キーワード(のように)も必要ありませんUNION CORRESPONDING
。幸いなことに、これはクエリがすべて、選択した SQL 製品 (SQL Server) で実行されることを意味します。
J Cooper によって暗示されたアプローチの 1 つは、a) 自然結合 (空集合である可能性があります) と、b) 自然結合が空集合である積の和集合です。
SELECT R.*, S.z
FROM R JOIN S ON R.y = S.y
UNION
SELECT R.*, S.z
FROM R CROSS JOIN S
WHERE NOT EXISTS ( SELECT *
FROM R JOIN S ON R.y = S.y );
別のアプローチは、積から対称差 (「相互に排他的なタプル」) を差し引いたもので、自然な結合は空集合ではありません。
SELECT R.*, S.z
FROM R CROSS JOIN S
EXCEPT
SELECT R.*, S.z
FROM R JOIN S ON R.y <> S.y
WHERE EXISTS ( SELECT *
FROM R JOIN S ON R.y = S.y );
SQL:
R1 = A equi_join B
R2 = A X B
R1
U
R2 not exists R1
これはこれに対する答えです。
宿題の期日が過ぎたので:
R1 = A equi_join B
R2 = A X B
R3 = R2.* (R1 X R2)
R4 = R2 - R3
return (R1 U R4)