5

SQL Server 2005 データベースで作成された次の T-SQL クエリを偶然見つけました。

Select s_bs.ScheduleHeaderId, 
       s_bs.ScheduleBatchScheduleId, 
       FlowRateOperational.FlowRate, 
       BatchScheduleFlowRateOperational.EffectiveStartTime, 
       BatchScheduleFlowRateOperational.EffectiveEndTime
From BatchSchedule as bs 
Inner Join ConnectionPoint as cp on bs.ConnectionPointId = cp.ConnectionPointId 
Inner Join ScheduleBatch as s_b 
Inner Join ScheduleConnectionPoint as s_cp 
Inner Join ScheduleBatchSchedule as s_bs 
            on s_cp.ScheduleConnectionPointId = s_bs.ScheduleConnectionPointId 
            on s_b.ScheduleBatchId = s_bs.ScheduleBatchId 
            on cp.ConnectionPointName = s_cp.ConnectionPointName and bs.BatchID = s_b.BatchID 
Inner Join BatchScheduleFlowRateOperational on bs.BatchScheduleId = BatchScheduleFlowRateOperational.BatchScheduleId 
Inner Join FlowRateOperational on BatchScheduleFlowRateOperational.FlowRateOperationalId = FlowRateOperational.FlowRateOperationalId

私は SQL の専門家ではありませんが、少なくともテーブルを結合する方法は知っていると思います。この方法でテーブルを結合する方法はこれまで見たことがありません。

JOINS の後に複数の ON 句を一緒に使用すると、異なる結果が生成されたり、パフォーマンスが向上したりしますか?

この人が結合を移動して、対応する JOIN の横に ON 句を保持できなかったのはなぜですか?

この「謎」に光を当ててくれてありがとう:)

4

5 に答える 5

2

内部結合のみの場合、結合の順序は関係ありません。結果セットは同じです。以下の 2 つのバージョンは同等です。

一般的な参加方法:

FROM 
    tableA AS a
  JOIN
    tableB AS b
      ON b.aid = a.aid
  JOIN
    tableC AS c
      ON c.bid = b.bid

そして、それほど一般的ではありません(括弧は優先順位を明確にするためだけにあることに注意してください。クエリのように安全に削除できます):

FROM 
    tableA AS a
  JOIN
      (   tableB AS b
        JOIN
          tableC AS c
            ON c.bid = b.bid
      )
    ON b.aid = a.aid

外部結合 ( LEFTRIGHT、またはFULL) がある場合、状況は異なります。上記のクエリで を に置き換えるJOINと、それらは同等ではなく、異なる結果セットが生成される場合があります。LEFT JOIN

(多くの) 結合の 1 つでも重要です。次の 2 つは同等ではありません。

FROM 
    tableA AS a
  LEFT JOIN
    tableB AS b
      ON b.aid = a.aid
  JOIN
    tableC AS c
      ON c.bid = b.bid

FROM 
    tableA AS a
  LEFT JOIN
          tableB AS b
        JOIN
          tableC AS c
            ON c.bid = b.bid

    ON b.aid = a.aid
于 2012-11-21T22:42:53.353 に答える
1

節はそれぞれのON直後に置くことができますINNER JOIN(私には見栄えがします)。ONしかし、後の結合の後に最初の 2 つの結合の句を配置することが避けられない場合があります。たとえば、結合条件を提供するテーブルは、JOINチェーンでまだ使用できません。たとえば、次のようになります。

SELECT * FROM 
A INNER JOIN 
B INNER JOIN 
C 
   ON B.Col1 = C.Col1 
   ON A.Col2 = C.Col2

両方のON節が参照していることに注意してください。Cしたがって、関連するON節が前に現れることはありません。最初に置くことで防ぐことができますがC、使い方によっては読みにくくなる場合があります。

上記は、構文の観点からのものです。私が気付いていないパフォーマンスに関する考慮事項もいくつかあるはずです。

于 2012-11-22T02:34:51.297 に答える
1

これは答えではなく、条件の配置を変更しただけです(私は思う)

Select s_bs.ScheduleHeaderId, 
       s_bs.ScheduleBatchScheduleId, 
       f.FlowRate, 
       b.EffectiveStartTime, 
       b.EffectiveEndTime
From 

BatchSchedule as bs Inner Join 

ConnectionPoint as cp on 
   cp.ConnectionPointId=bs.ConnectionPointId  Inner Join 

ScheduleBatch as s_b on
s_b.BatchID=bs.BatchID Inner Join 

ScheduleConnectionPoint as s_cp  on 
   s_cp.ConnectionPointName=cp.ConnectionPointName  Inner Join

ScheduleBatchSchedule as s_bs on 
   s_bs.ScheduleConnectionPointId = s_cp.ScheduleConnectionPointId Inner Join 

BatchScheduleFlowRateOperational b on 
b.BatchScheduleId = bs.BatchScheduleId  Inner Join 

FlowRateOperational f on 
f.FlowRateOperationalId=b.FlowRateOperationalId

where
s_bs.ScheduleBatchId = s_b.ScheduleBatchId 

whereまたは、条件をs_bs のand後のステートメントに入れることもできますがinner joining、チェーンの外にあるとより目立つと思います。

于 2012-11-21T22:30:02.963 に答える
1

内部結合では違いはありませんが、もちろん、他の種類の結合ではまったく異なる結果が生成されます。

不自然な例として、a LEFT JOIN (b CROSS JOIN c) ON b.a = a.a AND c.a = a.aテーブル b と c の両方に対して同時に null 以外の行のみを返しますがa LEFT JOIN b ON b.a = a.a LEFT JOIN c ON c.a = a.a、節を個別に評価します。

于 2012-11-21T22:37:03.077 に答える
0

それは醜く書かれているだけですが、私はそれが次と同じだと確信しています:

    Select s_bs.ScheduleHeaderId, 
       s_bs.ScheduleBatchScheduleId, 
       FlowRateOperational.FlowRate, 
       BatchScheduleFlowRateOperational.EffectiveStartTime, 
       BatchScheduleFlowRateOperational.EffectiveEndTime
From BatchSchedule as bs 
Inner Join ConnectionPoint as cp on bs.ConnectionPointId = cp.ConnectionPointId 
Inner Join ScheduleBatch as s_b on s_b.BatchID = bs.BatchID
Inner Join ScheduleBatchSchedule as s_bs on s_b.ScheduleBatchId = s_bs.ScheduleBatchId 
Inner Join ScheduleConnectionPoint as s_cp on s_cp.ScheduleConnectionPointId = s_bs.ScheduleConnectionPointId and s_cp.ConnectionPointName = cp.ConnectionPointName
Inner Join BatchScheduleFlowRateOperational on bs.BatchScheduleId = BatchScheduleFlowRateOperational.BatchScheduleId 
Inner Join FlowRateOperational on BatchScheduleFlowRateOperational.FlowRateOperationalId = FlowRateOperational.FlowRateOperationalId
于 2012-11-21T22:24:11.400 に答える