0

WHERE ... IN (サブクエリ) を使用するよりも、この SQL を記述する良い方法はありますか?

  SELECT device.mac, reseller.name, agent.name
  FROM device
  LEFT JOIN global_user
    ON device.global_user_id = global_user.id
  LEFT JOIN agent
    ON global_user.id = agent.global_user_id
  LEFT JOIN reseller
    ON global_user.id = reseller.global_user_id
        OR agent.reseller_id = reseller.id
  WHERE device.global_user_id IN (
    SELECT global_user_id
        FROM reseller
        WHERE id = '200'
  ) OR device.global_user_id IN (
    SELECT global_user_id
        FROM agent
        WHERE reseller_id = '200'
  );

特定の再販業者の下で、再販業者/エージェントの詳細を含むすべてのデバイスのリストを取得しようとしています。これには、リセラーに直接割り当てられたデバイスと、リセラーの下のエージェントに割り当てられたデバイスが含まれます。reseller.id は一意です。postgresql データベースで実行されます。

デバイスはエージェントとリセラーの両方に割り当てられます。エージェントは再販業者に割り当てられます。

このクエリは機能しますが、JOIN で OR を使用することはあまりなく、通常はサブクエリを避けようとします。このクエリの概念は頻繁に使用されるため、何かを見落としていないことを確認したいと思います。

フィードバックをお寄せいただきありがとうございます。

4

3 に答える 3

3

あなたはこれに旋風を巻き起こすことができます:

 SELECT device.mac, reseller.name, agent.name
  FROM device
  JOIN
  (
      SELECT global_user_id
      FROM reseller
      WHERE id = '200'
      UNION
      SELECT global_user_id
      FROM agent
      WHERE reseller_id = '200'
  ) r ON device.global_user_id = r.global_user_id
  LEFT JOIN global_user
    ON device.global_user_id = global_user.id
  LEFT JOIN agent
    ON global_user.id = agent.global_user_id
  LEFT JOIN reseller
    ON global_user.id = reseller.global_user_id
        OR agent.reseller_id = reseller.id

明確化: クエリのさまざまなバリエーションを試して、最高のパフォーマンスを発揮するクエリが得られるようにすることを常にお勧めします (ただし、多くの場合、さまざまなバリエーションを使用すると、クエリ オプティマイザーによって同じ実行プランが生成されます)。SQL Server の観点から言えば、クエリが処理される順序は、JOIN が WHERE 句の前に最初に処理されることを意味します。したがって、理論的には、この JOIN アプローチは結果セットを早期に縮小する必要があります。

于 2010-02-05T20:33:29.937 に答える
1

これはどう?

SELECT d.mac, r.name, a.name
FROM device as d, global_user as g, agent as a, reseller as r
WHERE d.global_user_id = g.id
  AND g.id = a.global_user_id
  AND (g.id = r.global_user_id OR a.reseller_id = r.id)
  AND (r.id = '200' OR a.reseller_id = '200');
于 2010-02-05T20:43:35.607 に答える
1

サブクエリとIN句は、簡単に置き換えられる場合は避けるようにしています。私の理解が正しければDB model、このクエリでも同じ結果が得られるはずです。

SELECT      DISTINCT
            device.mac, reseller.name, agent.name
FROM        device
LEFT JOIN   global_user
        ON  device.global_user_id = global_user.id
LEFT JOIN   agent
        ON  global_user.id = agent.global_user_id
LEFT JOIN   reseller
        ON  global_user.id = reseller.global_user_id
        OR  agent.reseller_id = reseller.id
WHERE       reseller.id = '200'
        OR  agent.reseller_id = '200'
于 2010-02-05T20:49:27.293 に答える