英文:
Can we return multiple values in THEN in a CASE statement in Oracle SQL?
问题
在Oracle SQL中,你可以在CASE
语句的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')
);
在你的查询中,根据用户提供的学期代码(TERM_CODE),CASE
语句的THEN
部分返回不同的DETAIL_CODE
值。例如,如果用户输入的学期代码为202320,查询将选择第二个CASE
,并将DETAIL_CODE的值设置为('D', 'E', 'F')。希望这有助于解决你的问题。
英文:
Can we return multiple values in THEN
in a CASE
statement in Oracle SQL?
I want to get multiple values in the CASE
's THEN
statement, based on when I want to get multiple values in 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')
);
This is my query, here I want to get multiple Detail_Codes
in my THEN
based on the user given term code. So for each term code I have different detail codes to be taken for which I have used case when then. However I was unable to get the desired output.
Basically if user enters the term as 202320 then my query should pick second case and details codes should be ('D', 'E', 'F')
.
Can anyone please help me out with this or provide an alternate solution?
答案1
得分: 2
你不能从 CASE
表达式的 THEN
子句中返回一个表达式;它需要返回一个单一的标量值。另外,你有 AND t.DETAIL_CODE IN (SELECT t.DETAIL_CODE FROM ...
这就像是在执行 AND 1 IN (SELECT 1 FROM ...
。
相反,可以使用 AND
和 OR
:
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')
)
);
英文:
You cannot return an expression from the THEN
clause of a CASE
expression; it needs to return a single scalar value. Additionally, you have AND t.DETAIL_CODE IN (SELECT t.DETAIL_CODE FROM ...
which is just like doing AND 1 IN (SELECT 1 FROM ...
.
Instead, use AND
and OR
:
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'))
);
or use IN
with multiple parameters:
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')
)
);
答案2
得分: 0
以下是翻译好的部分:
也许你可以考虑创建一个包含详细代码的表,而不是在查询中硬编码值。这将保留你可以从任何 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
英文:
Maybe you could consider creating a table with detail codes instead of hardcoding the values in your query (or queries). It will keep the data that you could use from any sql or pl/sql.
For instance, if your details data table would be like below:
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
... then along with some terms sample data...
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
)
... you would select it like here:
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
答案3
得分: 0
以下是代码部分的翻译:
Yes, you can use objects for this including returning condition from case expression. Even with different types of parameters and algorithms using inheritance. Like this:
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')
;
Objects are created like this:
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;
/
这是你提供的代码的翻译部分。如果你需要进一步的解释或有其他问题,请随时提出。
英文:
Yes, you can use objects for this including returning condition from case expression. Even with different types of parameters and algorithms using inheritance. Like this:
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' ) ;
;
Objects are created like this:
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 ;
/
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论