1

ここに示すように、2 つのテーブルがあります

フェッチしようとしていますがnameregister変数 WHENregister変数に値が存在しません。

以下のクエリを使用すると、ここに表示されます。

SELECT t2.name, t1.register, t1.mydate 
FROM time t1
RIGHT JOIN user t2
ON t2.user_id=t1.user_id
WHERE (t1.register = 'absent' OR t1.register is null)

以下のクエリを使用すると、ここに示すように誤った結果が得られます。

SELECT t2.name, t1.register, t1.mydate 
FROM time t1
RIGHT JOIN user t2
ON t2.user_id=t1.user_id AND (t1.register = 'absent' OR t1.register is null)

私の質問は、上記のケースで異なる結果が得られる理由です。WHERE 条件を記述する必要がないように、ON 句自体で WHERE 条件を使用しています。

誰かが私を正しい方向に向けることができますか?

4

3 に答える 3

3

"t1.register = 'absent' OR t1.register is null"条件を WHERE 句に入れると結合後に適用されますが、ON 句に入れると結合に影響します。

それは絶対に正常で望ましい動作です:)

ここでは、それを WHERE 句に入れる必要があります:)

于 2012-06-16T12:37:36.943 に答える
1

私は通常、右結合を使用しませんが、代わりに左結合を使用します...それらは実質的に同じであり、結合のどのテーブルからレコードを取得するかだけです。Olivier が述べたように、WHERE 句は結合条件の後に適用されます。私は通常、何が欲しいかを尋ねることから始めます...あなたの場合、登録時間に関係なくすべてのユーザーをリストしたいです...だから、私は単にそれを次のように置きます

select
      u.Name,
      t.register,
      t.myDate
   from
      users u
         LEFT JOIN time t
            on u.user_id = t.user_id

私の左側のテーブル (常に必要) はユーザーです... 時間は右側のテーブルであり、読みやすさのために左右の相関関係を表す "ON" 結合条件を常に維持しようとします。

さて、これはまさにあなたが望むものではありませんが、私が始めるところです... さて、「不在」ステータスを適用する方法。上記はすでにすべてのユーザーを取得しており、「absent」が発生したエントリのみを表示する必要があるため、それを JOIN 部分に追加します。これは、表示することに関心のある唯一のエントリであるためです。

select
      u.Name,
      t.register,
      t.myDate
   from
      users u
         LEFT JOIN time t
            on u.user_id = t.user_id
          AND t.register = 'absent'

したがって、「absent」を含むレコードのみが、それぞれの register 値と mydate 値を表示します...他のレコードでも、すべての人を取得できます。WHERE 句は必要ありません。

ただし、特定のタイプまたはステータスのユーザーのみが必要な場合は、それを追加して、表示したい「ユーザー」を制限できます...など

select
      u.Name,
      t.register,
      t.myDate
   from
      users u
         LEFT JOIN time t
            on u.user_id = t.user_id
          AND t.register = 'absent'
   where
      u.SomeStatus = whatever
于 2012-06-16T13:09:16.797 に答える
0

あなたの問題は、クエリの実行順序に関連しています。通常の順番は

 From
 JOIN
 WHERE
 SELECT

したがって、最初の例では

SELECT t2.name, t1.register, t1.mydate 
FROM time t1
RIGHT JOIN user t2
ON t2.user_id=t1.user_id
WHERE (t1.register = 'absent' OR t1.register is null)

最初に、2 つのテーブルが条件に基づいて (内部結合を使用して) 結合され、次に、タイムt2.user_id=t1.user_idテーブルの一致しないすべての行が一時的な結果テーブルに追加されます。最後に、WHERE 句の条件が一時テーブルに適用され、最終結果が生成されます。(t1.register = 'absent' OR t1.register is null)

2番目の例では

SELECT t2.name, t1.register, t1.mydate 
FROM time t1
RIGHT JOIN user t2
ON t2.user_id=t1.user_id AND (t1.register = 'absent' OR t1.register is null)

最初に、2 つのテーブルが条件に基づいて (内部結合を使用して) 結合されますt2.user_id=t1.user_id AND (t1.register = 'absent' OR t1.register is null)次に、時間以降のすべての一致しない行が結果に追加されます。

そのすべてについて、2 つのクエリの結果は異なります。

INNER JOINを使用すると、 WHERE または ON 句の条件は同じ結果になります。OUTER JOIN (LEFT/RIGHT/CROSS)を使用する場合にのみ異なります。

于 2012-06-16T13:06:22.743 に答える