我有一个看起来像这样的表:
AMT TYPE
100 red, yellow, green, purple
200 red, green, blue, yellow
90 pink, blue, light red
......
我想要的是按颜色添加金额。例如,最终输出应为:
AMT TYPE
300 red
300 yellow
300 green
290 blue
190 other
请注意1.我不想在light red
中加入red
2.我希望将除红色,黄色,绿色,蓝色以外的所有颜色都包含在一个新类别"其他"。
我目前的代码是
select sum(red), ... from (
select
case when trim(regexp_substr(type, red',1,1,'i')) is not null
then amt
else 0 end as red
......
from mytable)
但它并没有解决我之前提到的问题。我也尝试了以下方法,但它变得如此缓慢,以至于它永远不会结束。 (或者这段代码可能有错误?)
select color, sum(amt)
from (
select trim(regexp_substr(type,'[^,]+', 1, level)) as color
from mytable
connect by level <= regexp_count(type, ',')+1)
group by color
我该如何解决这个问题?
谢谢!
答案 0 :(得分:0)
你有完整的颜色列表吗?
想象一下你做到了。让table color(name varchar2(...) not null primary key)
列出每种颜色。
然后你可以这样写:
select
color.name, sum(crazy_table.amt)
from
color, crazy_table -- the latter is your original data
where
crazy_table.type like '%, ' || color.name -- at the end of string
or
crazy_table.type like color.name || ', %' -- at the start of string
or crazy_table.type like '%, ' || color.name || ', %' -- middle
or
crazy_table.type = color.name -- single entry, no commas
or
color.name = 'other' and not exists ( -- no known color matches
select 1 from color as c2
where instr(crazy_table.type, c2.name) > 0
)
group by color.name
它会完全扫描crazy_table
,这可能是大的,在color
表上进行索引查找,这可能要小得多,所以性能应该没问题。
答案 1 :(得分:0)
以下查询可以获得所需的结果。它
1.首先根据OTN论坛上convert comma separated string into rows给出的737905解决方案,将颜色值分成不同的行。
2.使用CASE陈述来指定其他&#39;除红色,黄色,绿色和蓝色外的颜色类别。
3.按颜色分组
4.按预先确定的颜色顺序排序
WITH SPLIT_COLORS AS
(
SELECT
AMT,
TRIM(EXTRACT(column_value,'/e/text()')) COLOR
FROM
mytable x,
TABLE(XMLSEQUENCE(EXTRACT(XMLTYPE('<ROW><e>'
||REPLACE(type,',','</e><e>')
||'</e></ROW>'),'//e')))
)
SELECT
CASE
WHEN color NOT IN ('red', 'yellow', 'green', 'blue') THEN 'other'
ELSE color
END AS color,
SUM(amt) amt
FROM
SPLIT_COLORS
GROUP BY
CASE
WHEN color NOT IN ('red', 'yellow', 'green', 'blue') THEN 'other'
ELSE color
END
ORDER BY
CASE color
WHEN 'red' THEN 1
WHEN 'yellow' THEN 2
WHEN 'green' THEN 3
WHEN 'blue' THEN 4
ELSE 5
END;
您只能测试第一部分的输出(CTE&#39; s - 公用表格式),如下所示:
WITH SPLIT_COLORS AS
(
SELECT
AMT,
TRIM(EXTRACT(column_value,'/e/text()')) COLOR
FROM
mytable x,
TABLE(XMLSEQUENCE(EXTRACT(XMLTYPE('<ROW><e>'
||REPLACE(type,',','</e><e>')
||'</e></ROW>'),'//e')))
)
SELECT *
FROM SPLIT_COLORS;