你好,我觉得这是一个简单的问题,但无法弄清楚。我试图找到与另一列相关的最大数量并将其分组,出现的问题是其中一个值是一个字符串。
Name Value
Nate 0
Nate 1
Jeff 2
Nate 2
Nate 'Test'
对于我真正想要的数据'测试'等于1.但是如果我在这里使用MAX()函数,我将得到:
Name Value
Nate 'Test'
Jeff 2
我只能想到,如果我读过“测试”这样的话。为1然后使用max函数(我不知道该怎么做)或者可能以某种方式将MAX()重载到我自己的定义中。
感谢您提供任何帮助。
答案 0 :(得分:2)
在字符串列中存储混合数据通常是一个坏主意。
您可以使用案例表达式将特定字符串转换为固定值:
select max(case when value = 'Test' then '1' else value end) from ...
但是你仍在处理字符串,所以你可能想把它们转换为数字,以防止' 10'排序之前' 2'例如:
select max(to_number(case when value = 'Test' then '1' else value end)) from ...
或
select max(case when value = 'Test' then 1 else to_number(value) end) from ...
将CTE用于样本数据:
-- CTE for dummy data
with your_table (name, value) as (
select 'Nate', '0' from dual
union all select 'Nate', '1' from dual
union all select 'Jeff', '2' from dual
union all select 'Nate', '2' from dual
union all select 'Nate', 'Test' from dual
)
-- actual query
select name,
max(case when value = 'Test' then 1 else to_number(value) end) as value
from your_table
group by name;
NAME VALUE
---- ----------
Nate 2
Jeff 2
但是你必须覆盖所有无法明确或隐式转换为数字的值。
如果您想忽略非数字值,或者将它们全部视为相同的固定值,而不是将单个字符串映射到它们自己的数值,那么稍微容易一些。然后你可以编写一个试图转换任何字符串的函数,如果它得到任何异常,则返回null(或其他一些固定值)。
从12cR1开始,您甚至可以使用with a PL/SQL declaration而不是永久性的独立或打包功能,如果这是偶然的事情:
with
function hack_to_number(string varchar2) return number is
begin
return to_number(string);
exception
when others then
return 1;
end;
select name,
max(hack_to_number(value)) as value
from your_table
group by name;
NAME VALUE
---- ----------
Nate 2
Jeff 2
通过使用正确的数据类型,您可能最好还是重新设计数据模型以防止出现此类问题。
正如@DrYWit在评论中指出的那样,从12cR2你甚至不需要这样做,因为the to_number()
function内置了这个,如果你明确地称之为:
select name,
max(to_number(value default 1 on conversion error)) as value
from your_table
group by name;
答案 1 :(得分:0)
这个正则表达式怎么样"技巧"?
SQL> with your_table (name, value) as (
2 select 'Nate', '0' from dual
3 union all select 'Nate', '1' from dual
4 union all select 'Jeff', '2' from dual
5 union all select 'Nate', '2' from dual
6 union all select 'Nate', 'Test' from dual
7 )
8 select name, max(to_number(value)) mv
9 from your_table
10 where regexp_like (value, '^\d+$')
11 group by name;
NAME MV
---- ----------
Nate 2
Jeff 2
SQL>