0

我有 3 张桌子:Products, ProductProperties, Properties. 我需要获得所有没有“属性 B”的产品。表:

# Products          # Join table                  # Properties
+----+-----------+  +------------+-------------+  +-------------+---------------+
| id | name      |  | product_id | property_id |  | property_id | property_name |
+----+-----------+  +------------+-------------+  +-------------+---------------+
|  1 | Product 1 |  |          1 |           1 |  |           1 |   Propeprty A |
|  2 | Product 2 |  |          1 |           2 |  |           2 |   Propeprty B |
|  3 | Product 3 |  |          2 |           1 |  +-------------+---------------+
+----+-----------+  |          2 |           2 |
                    |          3 |           1 |
                    +------------+-------------+

在这种特殊情况下,我希望 Product 3 被退回

是否可以在单个数据库查询中获得所有必需的产品?实现这一目标的最小查询是什么?

已编辑。带有子查询的查询被认为是bad

4

5 回答 5

1
select * from Products P where not exists (select * from ProductProperties 
inner join Properties on ProductProperties .property_id = Properties property_id 
where P.product_id = ProductProperties.product_id and property_name = 'Propeprty B') -- *or whatever* 
于 2012-05-18T21:00:51.170 回答
1

我需要获得所有没有“Property B”的产品

逆问题。找到带有 PropertyB的那些,然后否​​定它。

从所有PropertyB属性开始:

SELECT
     Property_Id
FROM Properties 
WHERE
     Property_Name = 'Property B'

然后,找到有那些sProductId的s:Property_Id

SELECT
     ProductId
FROM ProductProperties
JOIN (
     --1st query
     SELECT
         Property_Id
     FROM Properties 
     WHERE
         Property_Name = 'Property B'
) as PropertyB ON
    ProductProperties.Property_Id = PropertyB.Property_Id  

然后,找到所有Product不在该集合中的 s:

SELECT
    ProductId
FROM Product
LEFT OUTER JOIN (
    --2nd query
    SELECT
        ProductId
    FROM ProductProperties
    JOIN (
        --1st query
        SELECT
            Property_Id
        FROM Properties 
        WHERE
            Property_Name = 'Property B'
    ) as PropertyB ON
       ProductProperties.Property_Id = PropertyB.Property_Id
) as ProductsWithPropertyB ON
     Products.ProductId = ProductsWithPropertyB.ProductId
WHERE
     ProductsWithPropertyB.ProductId IS NULL

然后,您可以简化一下:

SELECT
    ProductId
FROM Product
LEFT OUTER JOIN (
    SELECT
        ProductId
    FROM ProductProperties
    JOIN Properties ON
        ProductProperties.PropertyId = Properties.PropertyId
    WHERE
        Properties.Name = 'Property B'
) as ProductsWithPropertyB ON
     Products.ProductId = ProductsWithPropertyB.ProductId
WHERE
     ProductsWithPropertyB.ProductId IS NULL

或者,如果您更喜欢IN子句(服务器可能不在乎):

SELECT 
     ProductId 
FROM Products
WHERE
     ProductId NOT IN (
          SELECT ProductId FROM ProductProperties WHERE PropertyId IN (
              SELECT PropertyId FROM Properties WHERE PropertyName = 'Property B'
          )
     )
于 2012-05-18T21:15:18.670 回答
0
SELECT Products.ProductID, Products.Name, Properties.property_name FROM Products
INNER JOIN ProductProperties ON Products.product_ID = ProductProperties.product_ID
INNER JOIN Properties ON ProductProperties.Property_ID = Properties.Property_ID
WHERE Properties.Property_ID <> 2
于 2012-05-18T21:01:02.127 回答
0

似乎您想要一个 OUTER JOIN 和一个 WHERE 子句来恢复不匹配的属性。这是未经测试的,但是:

SELECT Products.* FROM 
Products RIGHT OUTER JOIN Join_Table 
  ON Products.ID = Join_Table.Product_ID
  AND Join_Table.Property_ID = 2
WHERE Products.ID IS NULL
于 2012-05-18T21:13:54.187 回答
-1

是(更正以删除潜艇),

    Select * from 
     Products pr
     left join jointable jt on pr.id = jt.product_id 
     join properties pr on jt.property_id = pr.property_id and pr.property_name = 'Property B'
 where jt.product_id is null
于 2012-05-18T21:02:39.547 回答