我在使用普通的旧SQL查询时遇到了一些问题(大部分时间都使用ORM的缺点:)。
我有2个表,PRODUCTS
和RULES
。在表RULES
中,我已经为产品定义了规则。我想要的是编写一个查询来获取所有已定义规则的产品。
规则由两种方式定义:
RULE
(ProductID
有值,SectorID
为NULL)RULE
(SectorID
为空)指定一个产品的ProductID
更多结果需要包含具有规则(product.ID - rule.ProductID
)的所有产品,以及在规则表(product.SectorID - rule.SectorID
)中的扇区中定义的所有产品。
此外,结果不能包含重复的产品(由productId
或RULES
中的SectorID
定义的产品)
示例:
产品
ID SectorID
1 1
2 1
3 1
4 2
5 3
6 3
规则
ID ProductID SectorID
1 1 NULL
4 NULL 1
5 6 NULL
预期结果
PRODUCTS with IDs : 1, 2, 3, 6
答案 0 :(得分:4)
我能想到的最简单的方式,但不一定是最快的方式。
SELECT * FROM products AS p WHERE
EXISTS (SELECT * FROM rules AS r WHERE p.ID = r.ProductID OR p.SectorID = r.SectorID)
答案 1 :(得分:3)
要获得匹配产品的完整产品行,这是一个简单的JOIN
。 DISTINCT
是必需的,因为产品可能与产品规则和扇区规则匹配,您只需要列出一次。
SELECT DISTINCT p.*
FROM products p
JOIN rules r
ON p.ID = r.ProductID
OR p.SectorID = r.SectorID
答案 2 :(得分:2)
执行两个查询并合并结果:
SELECT ProductID FROM Rules
WHERE ProductID IS NOT NULL
UNION
SELECT p.ID FROM Product p
INNER JOIN Rules r ON p.SectorID = r.SectorID
UNION将过滤掉重复的ID。假设您的示例已简化,您可以将其用作子查询以获取包含规则的所有产品的列表,并使用该列表连接其他表以返回所需数据。
另一种方法:
SELECT DISTINCT p.ID FROM Product p
INNER JOIN Rules r
ON p.ID = r.ProductID OR p.SectorID = r.SectorID
这些可能会也可能不会产生不同的执行计划。你应该检查,然后选择更快的。
答案 3 :(得分:1)
select distinct
ProductID
from rules
where ProductID is not null
union
select distinct
p.id
from PRODUCTS p
inner join
RULES r
on r.sectorid = p.sectorid
答案 4 :(得分:0)
我相信这样的事情应该有效:
SELECT DISTINCT p.id
FROM Products p
LEFT JOIN Rules r1 ON p.id = r1.productID
LEFT JOIN Rules r2 ON p.SectorID = r2.SectorID
WHERE r1.id IS NOT NULL OR r2.SectorID IS NOT NULL
ORDER BY p.id;