我有一个值为“ 1”,“ 0”或“”的表。该表有四列:p,q,r和s。
我需要帮助来创建一个case语句,以在属性等于1时返回值。
对于ID 14,case语句应返回“ s”。
对于ID 33,case语句应返回'p r s'。依此类推。
我是否需要提供一个包含所有可能组合的案例说明?还是有更简单的方法。以下是我到目前为止提出的内容。
case
when p = 1 and q =1 then "p q"
when p = 1 and r =1 then "p r"
when p = 1 and s =1 then "p s"
when r = 1 then r
when q = 1 then q
when r = 1 then r
when s = 1 then s
else ''
end
答案 0 :(得分:2)
一个解决方案可能是使用每个属性的大小写返回正确的值,并用修剪将其包围以除去尾随空格。
with tbl(id, p, q, r, s) as (
select 5,1,0,0,1 from dual union all
select 14,0,0,0,1 from dual
)
select id,
trim(regexp_replace(case p when 1 then 'p' end ||
case q when 1 then 'q' end ||
case r when 1 then 'r' end ||
case s when 1 then 's' end, '(.)', '\1 '))
from tbl;
真正的解决方案是修复数据库设计。该设计在技术上违反了Boyce-Codd的第四范式,因为它包含多个1个独立属性。应该将ID“具有”或“属于”属性p或q等事实分开。此设计应为3个表,即具有ID的主表,包含有关主ID可能具有的属性的信息(p,q,r或s)的查找表,以及在适当的地方将两者结合起来的关联表(假定ID)行可以具有多个属性,并且一个属性可以属于多个ID),这就是建模多对多关系的方法。
main_tbl main_attr attribute_lookup
ID col1 col2 main_id attr_id attr_id attr_desc
5 5 1 1 p
14 5 4 2 q
14 4 3 r
4 s
然后,查询该模型以构建您的列表将很容易,如果属性描述发生更改(仅需更改1个位置),则易于维护等。
像这样从中选择:
select m.ID, m.col1, listagg(al.attr_desc, ' ') within group (order by al.attr_desc) as attr_desc
from main_tbl m
join main_attr ma
on m.ID = ma.main_id
join attribute_lookup al
on ma.attr_id = al.attr_id
group by m.id, m.col1;
答案 1 :(得分:0)
您可以将串联与decode()
函数一起使用
select id, decode(p,1,'p','')||decode(q,1,'q','')
||decode(r,1,'r','')||decode(s,1,'s','') as "String"
from t;
如果字母之间需要空格,请考虑使用:
with t(id,p,q,r,s) as
(
select 5,1,0,0,1 from dual union all
select 14,0,0,0,1 from dual union all
select 31,null,0,null,1 from dual union all
select 33,1,0,1,1 from dual
), t2 as
(
select id, decode(p,1,'p','')||decode(q,1,'q','')
||decode(r,1,'r','')||decode(s,1,'s','') as str
from t
), t3 as
(
select id, substr(str,level,1) as str, level as lvl
from t2
connect by level <= length(str)
and prior id = id
and prior sys_guid() is not null
)
select id, listagg(str,' ') within group (order by lvl) as "String"
from t3
group by id;
答案 2 :(得分:0)
我认为,将列用于关系是一种不好的做法。
您应该有两个表,一个表称为arts,另一个表名为map art,如下所示:
ID - ART
1 - p
2 - q
3 - r
4 - 2
...
映射将您的基本ID映射到您的art-id,看起来像这样
MYID - ARTID
5 - 1
5 - 4
之后,您应该使用oracles枢轴运算符。它更动态