使用SQL查找具有2个条件的所有行(单独的表)

时间:2013-05-09 20:52:15

标签: sql

我在使用普通的旧SQL查询时遇到了一些问题(大部分时间都使用ORM的缺点:)。

我有2个表,PRODUCTSRULES。在表RULES中,我已经为产品定义了规则。我想要的是编写一个查询来获取所有已定义规则的产品。

规则由两种方式定义:

  1. 您只能为一个产品指定RULEProductID有值,SectorID为NULL)
  2. 您可以使用RULESectorID为空)指定一个产品的ProductID更多
  3. 结果需要包含具有规则(product.ID - rule.ProductID)的所有产品,以及在规则表(product.SectorID - rule.SectorID)中的扇区中定义的所有产品。

    此外,结果不能包含重复的产品(由productIdRULES中的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
    

5 个答案:

答案 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)

要获得匹配产品的完整产品行,这是一个简单的JOINDISTINCT是必需的,因为产品可能与产品规则和扇区规则匹配,您只需要列出一次。

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

An SQLfiddle to test with

答案 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   

这是SQL Fiddle

答案 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;

SQL Fiddle