3

これは私が本から得た質問です(どちらを覚えていないか)、それは次のようになります:

3つのテーブルがあります。

  • サプライヤーsupId, name
  • 製品prodId, name
  • 在庫supId, prodId

1つのクエリで、サプライヤXが持っているすべての製品(またはそれ以上)を在庫に持っているすべてのサプライヤを見つける必要があります(サプライヤXが持っているとしましょうsupId=1)。

(したがって、サプライヤ1の在庫にバナナとリンゴがある場合は、少なくともバナナとリンゴを扱っているすべてのサプライヤを見つける必要があります)

標準SQLのみ(結合を含む)を使用できます。

どうやらこれは既知の問題/質問です、あなたはこの質問をチェックする必要があります: SQLの結果をhas-many-through関係でフィルタリングする方法 (優れたソリューションと分析)

4

2 に答える 2

6

その問題は、関係除算として知られています。

1つの解決策は二重否定です。サプライヤXによって提供された製品が存在せず、サプライヤによって提供されていないすべてのサプライヤを選択できます。

select  distinct other_supplier.SupID
from    Inventory other_supplier
where   not exists
        (
        select  *
        from    Inventory supplier_X
        where   supplier_X.supId = 1 -- For supplier X
                and not exists
                (        
                select  *
                from    Inventory other_product
                where   other_supplier.supId = other_product.Supid
                        and supplier_X.prodId = other_product.prodId
                )
        )

SQLFiddleでの実例。

于 2013-01-14T12:48:49.957 に答える
1

このソリューションは、パラメーター定義を除いて、標準SQLを使用していると思います。

DECLARE @supplierX int = 4

SELECT 
  [s].[supid],
  [s].[name]
FROM [Inventory] [i1]
INNER JOIN [Inventory] [i2] ON [i1].[prodid] = [i2].[prodid]
INNER JOIN [Supplier] [s] ON [i1].[supid] = [s].[supid]
WHERE
  [i1].[supid] <> @supplierX
  AND [i2].[supid] = @supplierX
GROUP BY 
  [s].[supid],
  [s].[name]
HAVING 
  COUNT(*) >= (SELECT COUNT(*) FROM [Inventory] [i3] WHERE [i3].[supid] = @supplierX)

フィドルはここにあります

上記のクエリの内訳:

  • サプライヤXが在庫に持っている製品の数を決定します(count(*)
  • 他のサプライヤーがsupplierXと共有する製品を決定する(joinprodidによる)
  • 共有製品の数が、supplierXの在庫にある製品の数以上であることを確認してください(HAVING COUNT() >= ...
于 2013-01-14T13:07:15.833 に答える