Oracle SQL - 从案例中多次返回

Posted

技术标签:

【中文标题】Oracle SQL - 从案例中多次返回【英文标题】:Oracle SQL - Multiple return from case 【发布时间】:2018-05-07 10:33:05 【问题描述】:

我可能试错了。我正在寻找任何最好的方法。

要求:

我的查询基于几个字段连接 4-5 个表。

我有一个名为产品 ID 的列。在我的表中有 150 万行。在这 10% 的行中,产品 ID 具有以下属性

A300X-%
A500Y-%

300,500、700 是有效的型号。 X 和 Y 是分类。我的查询选择了所有系统。

我有一张支票如下

CASE
WHEN PID LIKE 'A300X%'
THEN 'A300' 
...
END AS MODEL

同样

CASE
WHEN PID LIKE 'A300X%'
THEN 'X'
...
END AS GENRE

我正在寻找下面的最佳选择

    如何结合这两个 case 语句并添加另一个 [第三个] 案例,该案例将包含这两个案例。即
CASE 
    WHEN desc in ('AAA')
         First Case
         Second Case
    ELSE
         don't do anything for other systems
    END

    是否有任何正则表达式方法可以做到这一点?先于 - 取字符串。寻找 X、Y 以及 300,500,700。

    还有其他方法吗?还是通过代码做是最好的方式?

有什么建议吗?

编辑:

示例说明:

AAA,
SoftwARE, 
sw-app

我的查询选择了所有的 desc。但是这个案子应该只针对 AAA。

而有效的模型是

A300X-2x-P
A500Y-5x-p
A700X-2x-p
A50CE-2x-P

我只需要考虑 300,500,700。以及以上两种情况。

预期结果:

MODEL     GENRE
A300      X
A500      Y
A300      Y

【问题讨论】:

请显示更多示例数据。如果您需要在这两个 CASE 表达式中使用别名的两列,那么不清楚为什么您只需要一个列。 您是否知道(我猜您知道,但不得不问)% 用作通配符,这意味着 123abcdefg%123456789dfdgffdg 都将匹配 123%(与like)。 @TimBiegeleisen 我添加了更多数据。请检查。 @Gops AB:不,Tim 说的是,我们不明白你如何从case when 一次返回两件东西。因此,请显示预期结果,即不仅是字符串列表,还包括结果应包含的列。会有模型栏吗?会有流派专栏吗?会有另一列以某种方式组合这些吗?请出示。 @ThorstenKettner 我添加了预期的输出列。请检查并让我知道。是的,会有一个模型栏和一个流派栏。没有合并的列。 【参考方案1】:

问:如何结合两个 CASE statement 表达式

每个CASE 表达式都将返回一个值。如果要求在结果集中返回两个单独的列,则需要在 SELECT 列表中使用两个单独的表达式。

例如:

DESC  PID           model_number  genre
----  ----------    ------------  ------
AAA   A300X-2x-P    300           X 
AAA   A500Y-5x-p    500           Y
AAA   A700X-2x-p    700           X
AAA   A50CE-2x-P    (NULL)        (NULL)
FOO   A300X-2x-P    (NULL)        (NULL)

需要一个表达式来返回model_number 列,以及一个单独的表达式来返回genre 列。

单个表达式不可能返回两个单独的列。


问:并添加另一个[第三个] 案例,它将包含这两种情况。

CASE 表达式返回一个值;我们几乎可以在 SQL 语句中可以使用值的任何地方使用 CASE 表达式,包括在另一个 CASE 表达式中。

我们还可以将WHEN 测试中的多个条件与ANDOR 结合起来

作为组合条件和嵌套 CASE 表达式的示例...

 CASE 
 WHEN (    ( t.PID LIKE '_300%'  OR t.PID LIKE '_500%'  OR t.PID LIKE '_700%' )
       AND ( t.DESC = 'AAA' )
      )
 THEN CASE 
        WHEN ( t.PID LIKE '____X%' )
        THEN 'X'
        WHEN ( t.PID LIKE '____Y%' )
        THEN 'Y'
        ELSE NULL
      END
 ELSE NULL
 END AS `genre`

还有其他表达式会返回等价的结果;此处显示的示例不一定是最佳表达方式。它只是作为组合条件和嵌套 CASE 表达式的演示。

请注意,要返回另一列 model,我们需要在 SELECT 列表中包含另一个表达式。需要重复类似的条件;不能在另一个 CASE 表达式中引用 WHEN 条件。

【讨论】:

【参考方案2】:

根据您的示例数据,这样的逻辑会起作用:

(CASE WHEN REGEXP_LIKE(PID, '^A[0-9]3[A-Z]-')
      THEN SUBSTR(PID, 1, 4)
      ELSE PID
 END) AS MODEL

(CASE WHEN REGEXP_LIKE(PID, '^A[0-9]3[A-Z]-')
      THEN SUBSTR(PID, 5, 1)
      ELSE PID
 END) AS GENRE

这假定“型号”始终以“A”开头,后跟三位数字(如您的示例数据中所示)。如果型号比较复杂,你可能需要regexp_substr()来提取你想要的值。

【讨论】:

很好,看起来不错。让我试试这个并立即回复您 如何将两个结果放入一个字段中?我问是因为从理论上讲,它们都可以返回结果,不是吗? Gordon,您的解决方案使用了正则表达式,这比我想象的要好得多。但它仍然进行两次检查。不是吗? @GopsAB 。 . .如果您将表达式放在子查询中,您可以进行一次检查。

以上是关于Oracle SQL - 从案例中多次返回的主要内容,如果未能解决你的问题,请参考以下文章

Oracle SQL 性能问题 - 如何使查询停止运行并在找到第一个实例时返回

Oracle SQL 查询中的常量

Oracle Group by NULL 中的 SQL 返回多行

如何从 Oracle PL/SQL 函数中返回现有表中的记录?

限制从 Oracle 中的 SQL 查询返回的记录

Oracle PL/SQL块之函数