3

这是我从一本书中得到的一个问题(不记得是哪个),它是这样的:

你有三个表:

  • 供应商( supId, name)
  • 产品( prodId, name)
  • 库存( supId, prodId)

您需要通过一次查询找到所有在其库存中拥有供应商 X 拥有的所有产品(或更多)的供应商(假设供应商 X 是具有 的供应商supId=1)。

(所以如果供应商 1 在他的库存中有香蕉和苹果,你需要找到所有至少有香蕉和苹果的供应商)

您只能使用标准 SQL(包括连接)。

显然这是一个已知问题/问题,您应该查看这个问题: How to filter SQL results in a has-many-through relationship (优秀的解决方案和分析)

4

2 回答 2

6

这个问题被称为关系划分

一种解决方案是双重否定。您可以选择不存在供应商 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
                )
        )

SQL Fiddle 上的实时示例。

于 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(*))
  • 确定其他供应商与供应商X 共享的产品(join按prodid)
  • 确保共享产品的数量大于或等于供应商X 在其库存中的产品数量 ( HAVING COUNT() >= ...)
于 2013-01-14T13:07:15.833 回答