棘手的 sql 查询 - 寻找替代供应商(关系部门)
Posted
技术标签:
【中文标题】棘手的 sql 查询 - 寻找替代供应商(关系部门)【英文标题】:tricky sql query - finding alternative supplier( relational division ) 【发布时间】:2013-01-14 12:39:35 【问题描述】:这是我从一本书中得到的一个问题(不记得是哪个),它是这样的:
你有三个表:
供应商 (supId, name
)
产品 (prodId, name
)
库存 (supId, prodId
)
您需要通过一次查询找到所有库存中有供应商 X 拥有的所有产品(或更多)的所有供应商(假设供应商 X 是带有supId=1
的那个)。
(所以如果供应商 1 的库存中有香蕉和苹果,您需要找到所有至少有香蕉和苹果的供应商)
您只能使用标准 SQL(包括连接)。
显然这是一个已知问题/问题,您应该查看这个问题: How to filter SQL results in a has-many-through relation (优秀的解决方案和分析)
【问题讨论】:
【参考方案1】:这个问题被称为relational division。
一种解决方案是双重否定。您可以选择不存在供应商 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
)
)
Live example at SQL Fiddle.
【讨论】:
次要细节,但“other_supplier”也列出了“supplier_X”。它在问题中明确提到,但不符合您的命名。 您提供的链接非常好!我不知道操作的名称。谢谢!【参考方案2】:我相信此解决方案使用标准 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)
找到了一个小提琴here。
上述查询的细分:
确定供应商 X 库存中的产品数量 (count(*)
)
确定其他供应商与供应商X 共享的产品(join
by prodid)
确保共享产品的数量大于或等于供应商 X 库存中的产品数量 (HAVING COUNT() >= ...
)
【讨论】:
这也是一个很好的答案,我希望我能接受这两个答案:-) 我也希望! :-D 我也喜欢@Andomar 的回答,因为他甚至不需要加入。以嵌套的“不存在的地方”为代价,但仍然存在。 要符合标准 SQL(参数/程序代码),您需要用分号终止语句并删除方括号(在这种情况下无论如何都是多余的)。以上是关于棘手的 sql 查询 - 寻找替代供应商(关系部门)的主要内容,如果未能解决你的问题,请参考以下文章