有条件地使用 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的主要内容,如果未能解决你的问题,请参考以下文章