4

SQLでテーブルを結合するときにループを作成しないように教えられたことを覚えています。実際、ビジネス オブジェクトを使用すると、ユニバースで定義したスキーマにループがあるかどうかもわかります。
この声明についてウェブで検索しようとしましたが、参考文献を見つけることができませんでした。
なぜこれを行うのは危険なのですか?

編集:多分私は簡潔すぎました。

私の質問は、「FOR LOOP」などを意図したループに関するものではありませんでした。SELECT ステートメントの WHERE 句のようなものについて話していました。

WHERE TABLE1.foo = TABLE2.foo
  AND TABLE2.bar = TABLE3.bar
  AND TABLE3.baz = TABLE1.baz

リレーションを描画すると、結合に「ループ」が表示されます。これは、正確性および/またはパフォーマンスの観点から危険ですか?
ありがとうございます。

編集 2: 例を追加しました。

例を考えただけです。おそらくそれは最善ではないかもしれませんが、理解するのに役立つと思います。

------------          -----------------      ----------------------
- DELIVERY -          - DELIVERY_DATE -      -  DELIVERY_DETAILS  -
------------          -----------------      ----------------------
- id       - <---     - id            - <----- date_id            -
- company  -     |----- delivery_id   -      - product            -
- year     -          - date          -      - quantity           -
- number   -          -----------------      - datetime_of_event  - 
- customer -                                 ----------------------
- ----------          

             1 <-----> N               1 <----> N
  • DELIVERY テーブルでは、すべての配送が 1 回だけ表示されます
  • DELIVERY_TABLE には、配送が処理されたすべての日付のリストがあります。そのため、お届けまでに数日かかる場合がございます。
  • 最後の表には、すべての配送の詳細があります。したがって、このテーブルでは、配送の準備に関連するすべてのイベントを追跡します

したがって、カーディナリティは、テーブルの各カップルに対して 1:N です。

結合は非常に簡単です:

DELIVERY.id = DELIVERY_DATE.delivery_id AND 
DELIVERY_DATE.id = DELIVERY_DETAILS.date_id  

ここで、特定の日付の配達に関するその他の情報が含まれている別のテーブルに参加したいとします。それを定義しましょう:

------------  
- EMPLOYEE -
------------
- company  -
- year     -
- number   -
- date     -
- employee -
------------

結合は次のようになります。

DELIVERY.id = DELIVERY_DATE.delivery_id AND 
EMPLOYEE.company = DELIVERY.company AND
EMPLOYEE.year = DELIVERY.year AND
EMPLOYEE.number = DELIVERY.number AND
EMPLOYEE.date = DELIVERY_DATE.date  

要約すると、DELIVERY と DELIVERY_DATE の両方に EMPLOYEE を参加させ、参加にサイクルを持たせます。
このように書き直すべきでしょうか?

EMPLOYEE.company = DELIVERY.company AND
EMPLOYEE.year = DELIVERY.year AND
EMPLOYEE.number = DELIVERY.number AND
EMPLOYEE.date IN (SELECT date FROM DELIVERY_DATE d WHERE d.delivery_id = DELIVERY.id)  

編集 3: ついにリンクが見つかりました

いつものように、リンクを探すのをあきらめると、リンクが見つかります。
したがって、この記事ではすべてを説明します。Business Objects に関連していますが、内容は一般的です。
お時間をいただきありがとうございます。

4

2 に答える 2

2

編集:更新から、これはテーブルが複数回使用される BO デザイナーに固有の問題であることがわかりますが、BO は結合句を自動的に結合し、結果セットを誤って (または意図せずに) 制限します。この質問は、実際にはサイクルとは何の関係もありません。それ自体は、同じクエリで複数のコンテキストでエンティティを使用することに関するものです。OPの懸念に実際には対処していませんが、元の回答を以下に残します。

免責事項:これは回答と質問の両方であるため、回答ではない回答です。それはおそらくコメントであるはずですが、質問/回答しない限りコメントすることはできませんが、私は本当に助けたいので、ここで物事が行われている方法でなくても、私ができる唯一の方法で行います. だから私を訴えてください。

短い答えはノーです。結合でループ (または「サイクル」) を避けるべきではありません。

さらに言えば、クエリは、探しているデータを生成するための正しい論理条件を宣言するように構築されます。多くの場合、同じ論理条件がさまざまな方法で確立される可能性があるため、ある方法が別の方法よりも好ましいかどうかを尋ねることが理にかなっている場合があります。これは、パフォーマンスが重要な場合に特に重要になります。しかし何よりもまず、クエリは正しい結果セットを返さなければなりません。これがどのように達成されるかは、基礎となるスキーマによって異なります。そして、これはあなたが本当に集中すべきことです。

あなたの例では、EMPLOYEE が DELIVERY テーブルに関して果たす役割はなぜですか? なぜそれらの列に参加するのですか? EMPLOYEE が配達と同じ「日付」を持っているとはどういう意味ですか? これが不自然な例であることは理解していますが、私が言おうとしている点は、結合がグラフにサイクルを作成するかどうかは、特定の結果セットの論理的意味が何であるかに完全に (まあ、主に) 依存しているということです。

また、JOIN 構文の問題については、JOIN...ON 句を使用する方が WHERE 句よりも適しています。これは、エンティティを結合するために必要なことをデータ フィルタリング操作から分離するためです。

于 2012-12-30T02:30:47.723 に答える
1

さて、あなたの質問は簡単です。where結合を実行するために句を使用しないでください。on句を使用する必要があります。参加は次のように表すことができます。

from Table1 join
     Table2
     on Table1.foo = Table2.foo join
     Table3
     on Table2.bar = Table3.bar and
        Table1.baz = Table3.baz

これが適切かどうかは、データ構造によって異なります。時々そうです。あなたはそれについて心配するべきではありません。

ちなみに、これを「ループ」とは呼びません。これは、プログラミングでは「forループ」に、SQLではネストされたループ結合に非常に関連しています。これを結合条件のサイクルと呼ぶ場合があります。

Wmax。。。新しい結合構文について。それは「ただの」好みの問題ではありません。from句の「、」は「相互結合」を意味します。ほとんどの場合、これは非常にコストのかかる操作です。何を達成したいのかを明確にすることをお勧めします。

FROM A cross join B

その意図については、次のよりもはるかに明確です。

FROM A, B

次に、「、」を省略しても、有効な構文があります。

FROM A B

ただし、これは非常に異なることを意味します(エイリアスBをテーブルAに割り当てます)。

3番目の理由は最も重要な理由です。left outer join古い構文には、、、right outer joinおよびを表現する方法がありませんfull outer join

したがって、より明確なクエリを記述し、エラーを回避し、より優れた機能にアクセスするには、新しい構文を学習する必要があります。

于 2012-12-29T15:03:24.523 に答える