棘手的 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() &gt;= ...)

【讨论】:

这也是一个很好的答案,我希望我能接受这两个答案:-) 我也希望! :-D 我也喜欢@Andomar 的回答,因为他甚至不需要加入。以嵌套的“不存在的地方”为代价,但仍然存在。 要符合标准 SQL(参数/程序代码),您需要用分号终止语句并删除方括号(在这种情况下无论如何都是多余的)。

以上是关于棘手的 sql 查询 - 寻找替代供应商(关系部门)的主要内容,如果未能解决你的问题,请参考以下文章

oracle 查找所有下级分类sql语句

SQL为每个部门选择最大销售额的日期[重复]

在 Oracle SQL 查询中选择最新的

SQL的练习,求答案!!!

sql 查询语句的练习

sql的查询语句