web-dev-qa-db-ja.com

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

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

SELECT *
FROM Table1
CROSS JOIN Table2

このようなSQL操作が特に役立つのはどのような状況ですか?

96
Llyle

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

select 
    size,
    color
from
    sizes CROSS JOIN colors

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

select
    hour,
    minute
from
    hours CROSS JOIN minutes

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

select
    specId,
    month
from
    reports CROSS JOIN months

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

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

85
Dave DuPlantis

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

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

13
Randy

テスト用のデータを生成します。

13
Ovidiu Pacurar

おそらく、これはおそらく質問に答えませんが、もしそれが本当なら(そして私もそれを確信していません)、それは楽しい歴史です。

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

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

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

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

11
James Curran

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

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

7
Kevin Dostalek

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

3
Joel Coehoorn

これは、クロス結合を使用して クロス集計レポートを作成 にする興味深い方法です。 Joe CelkoのSQL For Smarties で見つけて、数回使用しました。少しセットアップが必要ですが、時間を費やす価値があります。

2
Jeff Jones

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

1
thoroughly

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

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()などを使用してグループ化し、可能な限り最高の組み合わせを見つけます
1
HankerPL