首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >递归sql问题

递归sql问题
EN

Stack Overflow用户
提问于 2008-12-18 14:42:21
回答 10查看 771关注 0票数 7

我有一个问题,我想通过SQL查询来解决。这将用作PoC (概念验证)。

问题是:

产品提供由一个或多个产品实例组成,一个产品实例可以属于多个产品提供。这可以在表中像这样实现:

代码语言:javascript
复制
PO | PI

-----

A | 10

A | 11

A | 12

B | 10

B | 11

C | 13

现在,我想从一组产品实例中获取产品报价。例如,如果我们发送10,11,13,返回的预期结果是B& C,如果我们只发送10,则结果应该为空,因为没有产品提供仅由10组成。发送10,11,12将导致A(不是A&B,因为12本身不是有效的产品提供)。

前提条件:传入的产品实例组合只能产生一个特定的产品组合,因此每个查询只有一个解决方案。

EN

回答 10

Stack Overflow用户

回答已采纳

发布于 2008-12-18 17:13:27

好的,我想我找到了。这符合您提供的约束。也许有一种方法可以进一步简化这一点,但它有点吞噬了我的大脑:

代码语言:javascript
复制
select distinct PO 
from POPI x 
where 
  PO not in (
    select PO 
    from POPI 
    where PI not in (10,11,12)
  ) 
  and PI not in (
    select PI 
    from POPI 
    where PO != x.PO 
      and PO not in (
        select PO 
        from POPI 
        where PI not in (10,11,12)
      )
  );

这只产生与所有其他结果不相交的填充给定集合的结果,我认为就是您所要求的。对于给定的测试示例:

  • 提供10,11,12产生A
  • 提供10,11,13产生B,C
票数 7
EN

Stack Overflow用户

发布于 2008-12-18 16:10:51

编辑:虽然我认为我的工作很好,但亚当的答案无疑更优雅,更高效-我就把我的留给子孙后代吧!

很抱歉,因为我知道这是一个Oracle的问题,因为我开始玩。这是一些我认为适用于所有上述情况的SQL2008代码……

代码语言:javascript
复制
declare @test table
(
    [PI] int
)
insert @test values (10), (11), (13)

declare @testCount int
select @testCount = COUNT(*) from @test

;with PO_WITH_COUNTS as 
(
        select  PO_FULL.PO, COUNT(PO_FULL.[PI]) PI_Count
        from    ProductOffering PO_FULL
        left
        join    (
                select  PO_QUALIFYING.PO, PO_QUALIFYING.[PI]
                from    ProductOffering PO_QUALIFYING
                where   PO_QUALIFYING.[PI] in (select [PI] from @test)
                ) AS QUALIFYING
                on      QUALIFYING.PO = PO_FULL.PO
                and     QUALIFYING.[PI] = PO_FULL.[PI]
        group by
                PO_FULL.PO
        having  COUNT(PO_FULL.[PI]) = COUNT(QUALIFYING.[PI])
)
select  PO_OUTER.PO
from    PO_WITH_COUNTS PO_OUTER 
cross 
join    PO_WITH_COUNTS PO_INNER
where   PO_OUTER.PI_Count = @testCount
or      PO_OUTER.PO <> PO_INNER.PO
group by
        PO_OUTER.PO, PO_OUTER.PI_Count
having  PO_OUTER.PI_Count = @testCount 
or      PO_OUTER.PI_Count + SUM(PO_INNER.PI_Count) = @testCount

不确定Oracle是否具有CTE,但只能将内部查询声明为两个派生表。外部查询中的交叉连接让我们找到具有所有有效项的产品组合。我知道这只能基于问题中的语句,即数据是这样的,即每个请求的集合只有一个有效的组合,否则就更复杂了,因为计数不足以删除其中有重复产品的组合。

票数 2
EN

Stack Overflow用户

发布于 2008-12-18 14:51:33

我面前没有一个数据库,但我的头上你想要的位置列表没有任何PI不在你的输入列表,即

代码语言:javascript
复制
select distinct po 
from tbl 
where po not in ( select po from tbl where pi not in (10,11,13) )

编辑:以下是其他示例:

当input PI =10,11,13时,内部选择返回A,因此外部选择返回B,C

当input PI = 10时,内部select返回A、B、C,因此外部select不返回行

当输入PI =10,11,12时,内部选择返回C,因此外部选择返回A,B

编辑: Adam已经指出,最后一个案例不符合只返回A的要求(这将教我如何快速),所以这还不是有效的代码。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/378040

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档