有没有比使用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,我通常会尝试避免使用子查询。这个查询概念会经常使用,所以我想确保我没有忽略某些东西。
感谢您的任何反馈。
答案 0 :(得分: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方法应该先缩减结果集。
答案 1 :(得分: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');
答案 2 :(得分: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'