0

私は3つのテーブルを持っています:Products、、。「プロパティB」を持たないすべての製品を取得する必要があります。テーブル:ProductPropertiesProperties

# 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 |
                    +------------+-------------+

この特定のケースでは、製品3が返されることを期待しています

単一のデータベースクエリ内で必要なすべての製品を取得することは可能ですか?それを達成するために可能な最小のクエリは何ですか?

編集済み。サブクエリを含むクエリは不良と見なされます。

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'

次に、これらの s を持つProductIds を見つけます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そのセットにないすべての を見つけます。

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 に答える