Есть ли лучший способ написать этот SQL, чем использовать WHERE ... IN (подзапрос)? - PullRequest
0 голосов
/ 05 февраля 2010

Есть ли лучший способ написать этот SQL, чем с помощью WHERE ... IN (подзапрос)?

  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 и обычно стараюсь избегать подзапросов. эта концепция запроса будет использоваться часто, поэтому я хотел бы убедиться, что я ничего не пропустил.

спасибо за любые отзывы.

Ответы [ 3 ]

3 голосов
/ 05 февраля 2010

Вы могли бы поднять это:

 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, то порядок, в котором обрабатывается запрос, означает, что соединения обрабатываются в первую очередь перед предложением WHERE. Таким образом, теоретически этот подход JOIN должен уменьшать результирующий набор ранее.

1 голос
/ 05 февраля 2010

Я стараюсь избегать подзапросов и предложения 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'
1 голос
/ 05 февраля 2010

Как насчет этого?

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');
...