在Oracle SQL中,我们可以在CASE语句中的THEN中返回多个值吗?

vs91vp4v  于 2023-03-22  发布在  Oracle
关注(0)|答案(3)|浏览(384)

我们可以在Oracle SQL中的CASE语句中返回THEN中的多个值吗?
我想在CASETHEN语句中获取多个值,这取决于我想在THEN中获取多个值的时间。

select IDt.,
       t.TERM_CODE,
       t.DETAIL_CODE
from   tableName t
where  t.TERM_CODE = :term
and    t.DETAIL_CODE IN (select t.DETAIL_CODE
                         from   tableName a
                         where  case when a.TERM_CODE = '202310'
                                then a.DETAIL_CODE in ('A','B','C')
                                when a.TERM_CODE = '202320'
                                then a.DETAIL_CODE in ('D','E','F')
                                when a.TERM_CODE = '202330'
                                then a.DETAIL_CODE in ('G','H','I')
                        );

这是我的查询,在这里我想得到多个Detail_Codes在我的THEN基于用户给定的术语代码.因此,对于每个术语代码,我有不同的详细代码,我已经使用的情况下,然后采取.然而,我无法得到所需的输出.
基本上,如果用户输入的术语为202320,那么我的查询应该选择第二种情况,详细代码应该是('D', 'E', 'F')
有人能帮我解决这个问题吗?或者提供一个替代的解决方案?

hgqdbh6s

hgqdbh6s1#

不能从CASE表达式的THEN子句返回表达式;它需要返回一个标量值。另外,你有AND t.DETAIL_CODE IN (SELECT t.DETAIL_CODE FROM ...,就像做AND 1 IN (SELECT 1 FROM ...一样。
使用ANDOR

select ID,
       TERM_CODE,
       DETAIL_CODE
from   tableName
where  TERM_CODE = :term
and    DETAIL_CODE IN (select DETAIL_CODE
                       from   tableName
                       where  (TERM_CODE = '202310' AND DETAIL_CODE in ('A','B','C'))
                       OR     (TERM_CODE = '202320' AND DETAIL_CODE in ('D','E','F'))
                       OR     (TERM_CODE = '202330' AND DETAIL_CODE in ('G','H','I'))
                      );

或者使用带有多个参数的IN

select ID,
       TERM_CODE,
       DETAIL_CODE
from   tableName
where  TERM_CODE = :term
and    DETAIL_CODE IN (select DETAIL_CODE
                       from   tableName
                       where  (TERM_CODE, DETAIL_CODE) IN (
                                ('202310', 'A'),
                                ('202310', 'B'),
                                ('202310', 'C'),
                                ('202320', 'D'),
                                ('202320', 'E'),
                                ('202320', 'F'),
                                ('202330', 'G'),
                                ('202330', 'H'),
                                ('202330', 'I')
                              )
                      );
hc8w905p

hc8w905p2#

也许你可以考虑创建一个带有详细代码的表,而不是在你的查询(或查询)中硬编码值。它将保留你可以从任何sql或pl/sql使用的数据。
例如,如果您的详细信息数据表如下所示:

ID     TERM_ID  DETAIL_CODE
----------  ----------  -----------
         1           1  A
         2           1  B
         3           1  C
         4           2  D
         5           2  E
         6           2  F
         7           3  G
         8           3  H
         9           3  I

。。。然后沿着一些术语样本数据。。

WITH
    tbl_terms (ID, TERM_CODE) AS
        (
            Select 1, '202310'  From dual Union All
            Select 2, '202320'  From dual Union All
            Select 3, '202330'  From dual           
        ),
    tbl_term_details (ID, TERM_ID, DETAIL_CODE) AS
        (
            Select 1, 1, 'A' From Dual Union All
            Select 2, 1, 'B' From Dual Union All
            Select 3, 1, 'C' From Dual Union All
            Select 4, 2, 'D' From Dual Union All
            Select 5, 2, 'E' From Dual Union All
            Select 6, 2, 'F' From Dual Union All
            Select 7, 3, 'G' From Dual Union All
            Select 8, 3, 'H' From Dual Union All
            Select 9, 3, 'I' From Dual 
        )

你可以像这样选择:

Select        t.ID, t.TERM_CODE, td.DETAIL_CODE
From          tbl_terms t
Inner Join    tbl_term_details td ON(td.TERM_ID = t.ID)
Where         t.TERM_CODE = :term 

Result for :term = '202310'
        ID TERM_CODE DETAIL_CODE
---------- --------- -----------
         1 202310    A
         1 202310    B
         1 202310    C
tuwxkamq

tuwxkamq3#

是的,你可以使用对象来实现这个,包括从case表达式返回条件。即使是不同类型的参数和算法使用继承。像这样:

select * from
(
select 'A' as value , 'scalar' as check_type from dual
union all
select 'b' , 'array' from dual
) s1
where
  (
  case 
  when s1.check_type = 'scalar' then t_test_child_scalar ( 'D' )
  when s1.check_type = 'array' then t_test_child_array ( t_string_array ( 'b' , 'C' ) )
  end
  ).check_in ( s1.value ) = t_test_result ( 'Y' , 'N' ) ;
;

对象是这样创建的:

CREATE OR REPLACE TYPE t_string_array AS TABLE OF VARCHAR2 ( 32767 )
;
CREATE OR REPLACE TYPE t_test_result force AS OBJECT
( is_in varchar2 ( 1 char )
, is_capital varchar2 ( 1 char )
)
;
CREATE OR REPLACE TYPE t_test_parent force AS OBJECT 
( v_dummy number
, NOT INSTANTIABLE MEMBER FUNCTION check_in ( i_value string )
  RETURN t_test_result
)
NOT INSTANTIABLE NOT FINAL
;
CREATE OR REPLACE TYPE t_test_child_scalar UNDER t_test_parent
( v_value varchar2 ( 1 char )
, CONSTRUCTOR FUNCTION t_test_child_scalar
  ( i_value string
  )
  RETURN SELF AS RESULT
, OVERRIDING MEMBER FUNCTION check_in ( i_value string )
  RETURN t_test_result
)
;
CREATE OR REPLACE TYPE t_test_child_array UNDER t_test_parent
( v_array t_string_array
, CONSTRUCTOR FUNCTION t_test_child_array
  ( i_array t_string_array
  )
  RETURN SELF AS RESULT
, OVERRIDING MEMBER FUNCTION check_in ( i_value string )
  RETURN t_test_result
)
;
CREATE OR REPLACE TYPE BODY t_test_child_scalar AS

CONSTRUCTOR FUNCTION t_test_child_scalar
( i_value string
)
RETURN SELF AS RESULT
IS
BEGIN
  v_value := i_value ;
  RETURN  ;
END ;

OVERRIDING MEMBER FUNCTION check_in ( i_value string )
RETURN t_test_result
IS
  v_result t_test_result default new t_test_result ( null , null ) ;
BEGIN
  if i_value = v_value then
    v_result.is_in := 'Y' ;
  else
    v_result.is_in := 'N' ;
  end if ;
  
  if i_value = upper ( i_value ) then
    v_result.is_capital := 'Y' ;
  else
    v_result.is_capital := 'N' ;
  end if ;
  
  return v_result ;

END check_in ;

END ;
/
CREATE OR REPLACE TYPE BODY t_test_child_array AS

CONSTRUCTOR FUNCTION t_test_child_array
( i_array t_string_array
)
RETURN SELF AS RESULT
IS
BEGIN
  v_array := i_array ;
  RETURN  ;
END ;

OVERRIDING MEMBER FUNCTION check_in ( i_value string )
RETURN t_test_result
IS
  v_result t_test_result default new t_test_result ( null , null ) ;
BEGIN
  if i_value member of v_array then
    v_result.is_in := 'Y' ;
  else
    v_result.is_in := 'N' ;
  end if ;
  
  if i_value = upper ( i_value ) then
    v_result.is_capital := 'Y' ;
  else
    v_result.is_capital := 'N' ;
  end if ;
  
  return v_result ;

END check_in ;

END ;
/

相关问题