Oracle Query 根据结果集中的值获取单个结果

Posted

技术标签:

【中文标题】Oracle Query 根据结果集中的值获取单个结果【英文标题】:Oracle Query to get single result depending on values in result set 【发布时间】:2020-07-20 10:40:52 【问题描述】:
WITH T1 AS SELECT DISTINCT(DETAILS) FROM ( SELECT STATUS, PREREQUISITE_NM, 
    (case  when (STATUS='Completed' ) then 'Completed'
    when (STATUS='Pending' ) then 'Pending'
    when (STATUS='Failed' and PREREQUISITE_NM = 'Y') then 'Failed'
    when (STATUS='Failed' and PREREQUISITE_NM = 'N') then 'Completed'
    end )DETAILS FROM TABLE_LIST WHERE ID=1))
    T2 AS ( SELECT DETAILS FROM T1)

结果 1: 待定 失败 已完成。结果 2: 失败 已完成。

在上面的查询中,我们根据可用数据看到不同的结果集。我想在 T2 Block 中写一个查询,它应该输出为:

    对于 Pending/Failed/Completed:应该将 Pending 作为输出。 对于失败/完成:应将失败作为输出。 是否可以在不使用 PL SQL 块的情况下通过查询来实现这一点。喜欢用 WITH 子句?

我可以解释我的目标,例如

假设 T1 Block 给我的结果是三行 Pending、Failed、Completed 然后我希望 Pending 作为输出值。如果 T1 Block 给我的结果是 Failed, Completed 那么我想 Failed 作为输出值。如果 T1 块仅给出 Completed,则 Completed 将被视为输出值。

【问题讨论】:

你想同时得到两个结果吗?? 假设 T1 Block 给我的结果是三行 Pending、Failed、Completed 然后我希望 Pending 作为输出值。如果 T1 Block 给我的结果是 Failed, Completed,那么我想 Failed 作为输出值。如果 T1 块仅给出 Completed,则 Completed 将被视为输出值。 我发了一个答案,请在那里跟进 【参考方案1】:

感谢 Roberto 和 Barbaros Ozhan,两个答案都很有用。发布我的一位同事分享的另一种方式。

WITH T1 AS (
SELECT
DISTINCT(DETAILS) 
FROM (
  SELECT STATUS, PREREQUISITE_NM, 
 (
CASE 
WHEN (STATUS = 'Failed' ) THEN
           CASE WHEN PREREQUISITE_NM = 'Y' THEN 'Failed' 
                WHEN PREREQUISITE_NM = 'N' THEN 'Completed' 
           END 
         ELSE 
           STATUS
           END
)DETAILS FROM TABLE_lIST WHERE ID=1)
),
T2 AS
(
SELECT CASE 
WHEN EXISTS
( SELECT DETAILS FROM  T1 where DETAILS='Pending' )
THEN 'Pending'  
WHEN EXISTS
( SELECT DETAILS FROM T1 WHERE DETAILS='InProgress' )
THEN 'InProgress'  
WHEN EXISTS
(SELECT DETAILS FROM T1 where DETAILS='Failed' )
THEN 'Failed'  
ELSE 'Completed' END  as DETAILS from DUAL 
                 )SELECT * FROM T2

【讨论】:

【参考方案2】:

您可以使用ROW_NUMBER() Analytic 函数将这些状态值按字母顺序降序排列,以满足您的需要:

WITH T1 AS
(
SELECT DISTINCT (CASE
         WHEN (STATUS = 'Failed' ) THEN
           CASE WHEN PREREQUISITE_NM = 'Y' THEN 'Failed' 
                WHEN PREREQUISITE_NM = 'N' THEN 'Completed' 
           END 
         ELSE 
           STATUS 
         END) AS details
  FROM TABLE_LIST
 WHERE ID = 1
), T2 AS
(
 SELECT T1.*, ROW_NUMBER() OVER (ORDER BY details DESC) AS rn
   FROM T1
 )   
SELECT details
  FROM T2
 WHERE rn = 1 

【讨论】:

感谢您的回复。但正如我提到的,我只想返回一个值。根据我们在查询输出中获得的值,可能是 Pending、Failed 或 Completed。 非常感谢。查询正在使用可用状态。【参考方案3】:

在阅读了您的 cmets 之后,我想出了这个解决方案,这可能不是最好的,但最后给出了您期望的输出,基于您真正想要的是将 t1 中生成的行转换为t2

我使用自己的测试,请注意替换列或修改任何必要的内容以使其适应您自己的查询

SQL> desc my_test
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 C1                                                 NUMBER
 C2                                                 VARCHAR2(20)
 C3                                                 VARCHAR2(1)

SQL> select * from my_test ;

        C1 C2                   C3
---------- -------------------- -
         1 Failed               Y
         2 Completed            Y
         1 Pending              Y
         1 Pending              N

SQL>

所以,如果刚刚得到我的查询的第一部分

SQL> WITH T1 AS (
     SELECT DISTINCT c2 FROM ( SELECT c1,c2,
     case  when c2='Completed'  then 'Completed'
           when c2='Pending'    then 'Pending'
           when c2='Failed' and c3 = 'Y' then 'Failed'
           when c2='Failed' and c3 = 'N' then 'Completed'
           else c2
           end FROM my_test WHERE c1=1
                 ) )
select trim ( completed || ' ' || failed || ' ' || pending ) as result
from
(
select * from t1 pivot ( max(c2) for c2 in ( 'Completed' as Completed, 'Failed' as Failed, 'Pending' as Pending ) )
)
/  9   10   11   12   13   14   15

RESULT
--------------------------------------------------------------
Failed Pending

现在我只需要在该结果上构建一个案例(根据您自己的要求修改它)

SQL> WITH T1 AS (
            SELECT DISTINCT c2 FROM ( SELECT c1,c2,
                                                                                        case  when c2='Completed'  then 'Completed'
                                                  when c2='Pending'    then 'Pending'
                                                  when c2='Failed' and c3 = 'Y' then 'Failed'
                                                  when c2='Failed' and c3 = 'N' then 'Completed'
                                                                                        else c2
                                                                                        end FROM my_test WHERE c1=1
                 ) ) 
select 
case when result = 'Completed Failed Pending' then 'Pending' 
     when result = 'Completed Failed'         then 'Failed' 
     when result = 'Failed Pending'           then 'Failed' -- I guess
     when result = 'Completed Pending'        then 'Pending' -- I guess
end as output 
from (       
select trim ( completed || ' ' || failed || ' ' || pending ) as result 
from 
(                
select * from t1 pivot ( max(c2) for c2 in ( 'Completed' as Completed, 'Failed' as Failed, 'Pending' as Pending ) )
)
)
/

OUTPUT
-------
Failed

SQL>

【讨论】:

非常感谢。我会尝试给定的解决方案,并会更新你。

以上是关于Oracle Query 根据结果集中的值获取单个结果的主要内容,如果未能解决你的问题,请参考以下文章

从 Oracle 中的动态 SQL 获取结果集中的结果

如何使用 jdbc 从 Oracle 中的结果集中获取模式名称?

返回单个数据库结果的正确方法是什么?

Oracle SQL Query,用于拆分和计算列中的值的功能?

Oracle Sql Query 需要一天的时间才能使用 dblink 返回结果

如何使用代码点火器从 mysql 获取单个结果? [复制]