Oracle 查询根据结果集中的值获取单个结果
Oracle Query to get single result depending on values in result set
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 块中编写一个查询,该查询应将输出作为:
- for Pending/Failed/Completed : 应该给出 Pending 作为输出。
- 对于 Failed/Completed :应该给出 Failed 作为输出。
是否可以在不使用 PL SQL 块的情况下通过查询实现此目的。喜欢使用 WITH 子句?
我可以解释我的目标,例如
假设 T1 块给我的结果是三行待处理、失败、已完成,然后我想将待处理作为输出值。如果 T1 Block 给我的结果是“失败”、“已完成”,那么我想将“失败”作为输出值。如果 T1 块仅给出 Completed,则 Completed 将被视为输出值。
您可以使用 ROW_NUMBER()
分析函数将这些状态值按字母顺序降序排列,这将满足您的需要:
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
阅读您的评论后,我想出了这个解决方案,这可能不是最好的,但最后给出了您期望的输出,基于此您真正想要的是将 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>
感谢 Roberto 和 Barbaros Ozhan,这两个答案都是 useful.Posting 我的一位同事分享的另一种方式。
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
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 块中编写一个查询,该查询应将输出作为:
- for Pending/Failed/Completed : 应该给出 Pending 作为输出。
- 对于 Failed/Completed :应该给出 Failed 作为输出。
是否可以在不使用 PL SQL 块的情况下通过查询实现此目的。喜欢使用 WITH 子句?
我可以解释我的目标,例如
假设 T1 块给我的结果是三行待处理、失败、已完成,然后我想将待处理作为输出值。如果 T1 Block 给我的结果是“失败”、“已完成”,那么我想将“失败”作为输出值。如果 T1 块仅给出 Completed,则 Completed 将被视为输出值。
您可以使用 ROW_NUMBER()
分析函数将这些状态值按字母顺序降序排列,这将满足您的需要:
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
阅读您的评论后,我想出了这个解决方案,这可能不是最好的,但最后给出了您期望的输出,基于此您真正想要的是将 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>
感谢 Roberto 和 Barbaros Ozhan,这两个答案都是 useful.Posting 我的一位同事分享的另一种方式。
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