有条件地使用 CASE...WHEN - Oracle SQL

Posted

技术标签:

【中文标题】有条件地使用 CASE...WHEN - Oracle SQL【英文标题】:Conditionally use CASE...WHEN - Oracle SQL 【发布时间】:2019-09-30 20:00:50 【问题描述】:

我有两张这样的表:

tblOrders:OrderNo (pk)、CurrentStepNo (fk)

tblSteps:StepNo (pk)、OrderNo (fk)、StepName、StepType、StepStart、StepStop

tblOrders 包含大量关于我们的销售订单的信息,而tblSteps 包含大量关于构建我们销售的材料所需的正确顺序步骤的信息。

我正在尝试构建一个遵循此逻辑的查询:

"对于所有订单,从步骤表中选择当前步骤名称。如果 Step Type 等于 'XO',然后选择最近的 已完成(StepStop 不为空) 常规步骤(StepStop 为 等于'YY')"

我有以下疑问:

SELECT
    tblOrders.*,
    tblSteps.StepName    
FROM
    tblOrders
        INNER JOIN tblSteps 
                ON tblOrders.OrderNo = tblSteps.OrderNo
               AND tblOrders.CurrentStepNo = tblSteps.StepNo

成功返回给我处理中订单的当前步骤名称。我需要实现的是,当tblOrders.CurrentStepNo 的类型为'XO' 时,找到MAX(tblSteps.StepStop) WHERE tblSteps.StepType = 'YY'。但是,我无法将该逻辑放入我已经工作的查询中。

注意:对于本示例中缺少示例数据,我深表歉意。我通常会发布,但在这种情况下不能。这也不是作业题。

我已经查看了这些参考资料:

Case in Select Statement

https://blogs.msdn.microsoft.com/craigfr/2006/08/23/subqueries-in-case-expressions/

但到目前为止还没有运气。

我试过这个:

SELECT
    tblOrders.*,
    CASE
        WHEN tblSteps.StepType = 'XO' THEN (-- Some logic here)
        ELSE tblSteps.StepName
        END AS StepName    
 FROM
    tblOrders
        INNER JOIN tblSteps 
                ON tblOrders.OrderNo = tblSteps.OrderNo
               AND tblOrders.CurrentStepNo = tblSteps.StepNo

但我正在努力正确地制定逻辑

【问题讨论】:

【参考方案1】:

加入所有步骤,用ROW_NUMBER 对它们进行排名,并留在排名最高的位置:

select *
from
(
  select
    o.*,
    s.*,
    row_number() over 
      (partition by o.orderno
       order by case when s.steptype <> 'XO' and s.stepno = o.currentstepno then 1
                     when s.steptype <> 'YY' then 2
                     else 3 end, s.stepstop desc nulls last) as rn
  from tblorders o
  join tblsteps s on s.orderno = o.orderno
) ranked
where rn = 1
order by orderno;

【讨论】:

我知道我没有发布示例数据来测试。当StepType 不是 XO 时,它是如何工作的?我对这个解决方案如何满足上述帖子的要求感到困惑,你能解释一下吗? 查看连接。我将其所有步骤加入到订单中。然后我为每个订单的这些步骤编号(使用row_number() over (partition by o.orderno)。如果有一个 steptype 'XO' 与 currentstepno 匹配的步骤,它将获得 #1。接下来是 steptype 'YY' 行。我按stepstop降序对这些进行编号。因此,最高的获得下一个数字(即 #1 或 #2)。最后我只保留了#1。

以上是关于有条件地使用 CASE...WHEN - Oracle SQL的主要内容,如果未能解决你的问题,请参考以下文章

case when用法sql

case when用法

MySQL 条件, case when 和 if 方法

Sql文的where中使用case when

使用 Django 的 Case/When 查询集条件来设置多个值?

跨表使用group by,case when的问题