クロス結合の用途は何ですか?


105

クロス結合は、2つのセットのタプルに対してデカルト積を実行します。

SELECT *
FROM Table1
CROSS JOIN Table2

このようなSQL操作を特に便利にするのはどのような状況ですか?


36
この質問が閉じられたことは本当に悲しいことです。コミュニティWikiとしてマークされる可能性があると思いますが、建設的ではないと言うのは不当です。
Wayne Koorts、2016

1
同意する。これは私が持っていた正確な質問に答えました。
Hades

10
新しい開発者は、使用しているソフトウェアの特定の機能の影響を理解するのに苦労することがあります。このような質問は、主に次の議論がジュニア開発者が考慮しなかった多くの可能性を明らかにするので、新しい開発者にとって特に有用です。質問のフォーマットはせいぜい初歩的なものですが、「なぜこれが存在するのか」と尋ねるという点で、意図は正直に思われます。私はウェイン・コールツに同意します。casperOneがこれを閉じることを選択し、それを「建設的ではない」と言ったのは残念です。「建設的でない」部分は特に私をいらいらさせます。
Kaorie

回答:


93

特定の衣料品のサイズや色の情報など、完全に入力したい「グリッド」がある場合:

select 
    size,
    color
from
    sizes CROSS JOIN colors

たぶん、その日の1分ごとの行を含むテーブルが必要で、それを使用してプロシージャが毎分実行されたことを確認したいので、3つのテーブルをクロスする場合があります。

select
    hour,
    minute
from
    hours CROSS JOIN minutes

または、毎年、毎月適用する一連の標準レポート仕様があります。

select
    specId,
    month
from
    reports CROSS JOIN months

これらをビューとして維持することの問題は、ほとんどの場合、特に衣服に関して完全な製品を望んでいないことです。MINUSクエリにロジックを追加して、保持していない特定の組み合わせを削除できますが、他の方法でテーブルにデータを入力し、デカルト積を使用しない方が簡単な場合があります。

また、おそらく思ったよりも数行多いテーブルでクロス結合を試みたり、WHERE句が部分的または完全に欠落したりする可能性があります。その場合、DBAはその旨を速やかに通知します。通常彼または彼女は幸せではありません。


5
...その場合、DBAはその旨を速やかに通知します。通常彼または彼女は幸せではありません。...ハハ、本当!
RSW 2013年

2
@Dave:2番目の例は、1時間のCROSS JOIN分の値になりませんか?
Rakesh 2013

@Rakesh、良いキャッチ、私はタイプしているもの以外の何かを考えていました。修繕。
Dave DuPlantis 2013

1
2セットのID(おそらくcsv形式)が与えられ、1セットに従業員IDが含まれ、もう1セットにタスクIDが含まれている場合、クロス結合は非常に実用的だと想像できます。考えは、EmployeeTaskのM2Mテーブルがあるということです。csvをテーブル変数(または何か)に変換した場合、クロス結合を使用して、すべての特定のタスクをすべての特定の従業員に割り当てることができます。
SynBiotik 2014年


14

通常、ほとんどのデータベースクエリに完全なデカルト積が必要になることはありません。リレーショナルデータベースの強力な点は、必要な制限を適用して、不要な行をデータベースからプルしないようにすることができることです。

従業員のテーブルと実行する必要のあるジョブのテーブルがあり、1人の従業員が1つのジョブに割り当てられる可能性のあるすべてを確認したい場合は、1つの不自然な例が考えられます。


11

さて、これはおそらく質問に答えることはありませんが、それが真実であるなら(そして、私はそれさえ確信していません)、それは楽しい歴史のビットです。

Oracleの初期の頃、開発者の1人は、テーブルのすべての行を複製する必要があることに気付きました(たとえば、イベントのテーブルであり、「開始イベント」と「終了イベント」を別々に変更する必要があった可能性があります。エントリ)。2行だけのテーブルがある場合、クロス結合を実行して、最初のテーブルの列だけを選択し、必要なものを正確に取得できることに気付きました。そこで、彼は単純に「DUAL」と呼ばれるテーブルを作成しました。

後で、アクション自体がテーブルとは関係なくても、テーブルからの選択を介してのみ実行できる何かを実行する必要があります(おそらく彼は時計を忘れて、SELECT SYSDATE FROMを介して時間を読みたかったのです。 。)彼は自分のDUALテーブルがまだ横になっていることに気づき、それを使用しました。しばらくすると、彼は時間が2回出力されるのを見るのに疲れたので、最終的に行の1つを削除しました。

Oracleの他の人たちも彼のテーブルを使い始め、最終的にはそれを標準のOracleインストールに含めることが決定されました。

これが、行が1つしかないことだけが重要であるテーブルに「2」を意味する名前がある理由を説明しています。


8

キーは、「可能なすべての組み合わせを表示する」です。これらを他の計算フィールドと組み合わせて使用​​し、それらを並べ替え/フィルタリングしました。

たとえば、裁定取引(取引)アプリケーションを構築しているとします。ある価格で製品を提供する売り手と、ある費用で製品を求める買い手がいます。(潜在的な買い手と売り手を一致させるために)プロダクトキーでクロス結合を行い、コストと価格の間のスプレッドを計算してから、descを並べ替えます。これで、あなた(仲介者)に実行する最も収益性の高い取引を提供します。もちろん、ほとんどの場合、もちろん他の境界フィルター基準があります。


ああ!この説明は私にとって最も理にかなっています。この場合、複数の販売者が同じ製品を販売できるため、製品IDと販売者の間に関係がないため、INNER JOINは意味がありません。
moonman239

3

0から9までの数字が10行ある数字テーブルのようなものをとります。そのテーブルでクロスジョインを数回使用して、必要な行数の結果を取得し、結果に適切な番号を付けることができます。これには多くの用途があります。たとえば、それをdatadd()関数と組み合わせて、特定の年の毎日のセットを取得できます。



1

アイテムと日付の特定の組み合わせ(価格、在庫状況など)に対して発行したい一連のクエリがあるとします。アイテムと日付を別々の一時テーブルにロードし、クエリでテーブルをクロス結合することができます。これは、特に一部のデータベースではIN句の要素数が制限されているため、IN句の項目と日付を列挙する代わりの方法よりも便利な場合があります。


1

CROSS JOINを使用して、次のことを実行できます。-テスト目的でデータを生成します-すべてのプロパティを組み合わせます-たとえば、血液型(A、B、..)とRh-/ +などのすべての可能な組み合わせが必要です... --tune itあなたの目的のために;)-私はこの分野の専門家ではありません;)

CREATE TABLE "HR"."BL_GRP_01" 
("GR_1" VARCHAR2(5 BYTE));
REM INSERTING into BL_GRP_01
SET DEFINE OFF;
Insert into BL_GRP_02 (GR_1) values ('A');
Insert into BL_GRP_02 (GR_1) values ('B');
Insert into BL_GRP_02 (GR_1) values ('O');
Insert into BL_GRP_01 (GR_1) values (NULL);

CREATE TABLE "HR"."BL_GRP_02" 
("GR_1" VARCHAR2(5 BYTE));

REM INSERTING into BL_GRP_02
SET DEFINE OFF;
Insert into BL_GRP_02 (GR_1) values ('A');
Insert into BL_GRP_02 (GR_1) values ('B');
Insert into BL_GRP_02 (GR_1) values ('O');
Insert into BL_GRP_02 (GR_1) values (NULL);

CREATE TABLE "HR"."RH_VAL_01" 
("RH_VAL" VARCHAR2(5 BYTE));
REM INSERTING into RH_VAL_01
SET DEFINE OFF;
Insert into RH_VAL_01 (RH_VAL) values ('+');
Insert into RH_VAL_01 (RH_VAL) values ('-');
Insert into RH_VAL_01 (RH_VAL) values (NULL);

select distinct  a.GR_1 || b.GR_1 || c.RH_VAL as BL_GRP
from BL_GRP_01 a, BL_GRP_02 b, RH_VAL_01 c
GROUP BY a.GR_1, b.GR_1, c.RH_VAL;
  • 共通IDのない2つのテーブルの結合を作成し、max()などを使用してそれをグループ化して、可能な限り最高の組み合わせを見つけます。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.