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 的角度来看,处理查询的顺序意味着在 WHERE 子句之前首先处理 JOIN。所以理论上,这种 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 回答