5

我在使用普通的旧 SQL 查询时遇到了一些问题(大多数时候使用 ORM 的缺点:))。

我有 2 张桌子,PRODUCTS并且RULES. 在表中RULES,我为产品定义了规则。我想要的是编写一个查询来获取所有已定义规则的产品。

规则由两种方式定义:

  1. 您只能指定RULE一种产品(ProductID有值,SectorID为 NULL)
  2. 您可以使用( is NULL)指定RULE多个产品SectorIDProductID

结果需要包含具有规则 ( ) 的所有产品,以及在规则表 ( )product.ID - rule.ProductID中的扇区中定义的所有产品。product.SectorID - rule.SectorID

此外,结果不能有重复的产品(由productIdinRULES或 by定义的产品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
4

5 回答 5

4

我能想到的最简单的方法,但不一定是最快的。

SELECT * FROM products AS p WHERE
       EXISTS (SELECT * FROM rules AS r WHERE p.ID = r.ProductID OR p.SectorID = r.SectorID)
于 2013-05-09T20:57:02.640 回答
3

要获得匹配产品的完整产品行,只需一个简单的JOIN. 这DISTINCT是必需的,因为产品可能同时匹配产品规则和部门规则,并且您只希望它列出一次。

SELECT DISTINCT p.* 
FROM products p
JOIN rules r
  ON p.ID       = r.ProductID
  OR p.SectorID = r.SectorID

一个用于测试的 SQLfiddle

于 2013-05-09T21:00:13.557 回答
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

这些可能会或可能不会生成不同的执行计划。您应该检查并选择更快的那个。

于 2013-05-09T20:54:51.430 回答
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   

这是SQL 小提琴

于 2013-05-09T20:58:07.893 回答
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;

SQL小提琴

于 2013-05-09T21:12:01.523 回答