试图按generic_m_ai分组

时间:2013-07-15 16:12:29

标签: oracle oracle11g

我们当前的应用程序允许通过NLSSORT = generic_m_ai过滤数据,我也希望能够按照它进行分组。 目前使用小表对其进行测试,但保持'case'语句类似于真实查询

这就是我的表格创建方式:

create table alex_collate_test
(aaa varchar(30),
bbb varchar(30), primary key(aaa, bbb))
insert into alex_collate_test values ('hi', 'bye')
insert into alex_collate_test values ('HI', 'bye')
insert into alex_collate_test values ('hi', 'BYE')
insert into alex_collate_test values ('HI', 'BYE')
insert into alex_collate_test values ('next', 'howdy')

以下是常规小组:

select case when aaa is null or length(aaa) = 0 then '(blank) - '|| case when bbb is null then '' else bbb end  else aaa||' - '|| case when bbb is null then '' else bbb end  end mycolumn
from alex_collate_test
group by case when aaa is null or length(aaa) = 0 then '(blank) - '|| case when bbb is null then '' else bbb end  else aaa||' - '|| case when bbb is null then '' else bbb end  end

并获得:

hi - BYE                                                        
HI - BYE                                                        
hi - bye                                                        
next - howdy                                                    
HI - bye 

我正在关注MSSQL的'Collat​​e'代码,并将列包装在'NLSSORT'中:

select NLSSORT(case when aaa is null or length(aaa) = 0 then '(blank) - '|| case when bbb is null then '' else bbb end  else aaa||' - '|| case when bbb is null then '' else bbb end  end, 'NLS_SORT=generic_m_ai') mycolumn
from alex_collate_test
group by NLSSORT(case when aaa is null or length(aaa) = 0 then '(blank) - '|| case when bbb is null then '' else bbb end  else aaa||' - '|| case when bbb is null then '' else bbb end  end , 'NLS_SORT=generic_m_ai')

获得此输出:

0213021B01EF026701FE
023201FE0266025502130238026401F70267

起初它看起来像十六进制,我只需要转换为varchar,但如果你仔细看,它不是十六进制。它有'02' - 这不是像'hi'或'bye'这样的普通字符。

我的预期输出,或者说我想得到的是:

HI - BYE
next - howdy

2 个答案:

答案 0 :(得分:2)

也许使用MIN()可以解决这个问题

with qry as (
  select 
    case when aaa is null or length(aaa) = 0 then '(blank) - '|| 
    case when bbb is null then '' else bbb end  else aaa||' - '|| 
    case when bbb is null then '' else bbb end  
    end mycolumn 
  from alex_collate_test
)
select min( mycolumn ) mycolumn
from qry
group by NLSSORT( mycolumn, 'NLS_SORT=generic_m_ai')

这是sql fiddle的链接:http://sqlfiddle.com/#!4/6934c/2

答案 1 :(得分:1)

NLSSORT为您提供用于使用该值执行排序的字节,并且是RAW值。所以它没有直接用处。

但你可以间接地使用它来实现这一点。可能有更简单的方法,但使用基于排序顺序为您提供伪列的分析函数似乎有效:

select mygroupcolumn
from (
  select mycolumn, first_value(mycolumn)
    over (partition by NLSSORT(mycolumn, 'NLS_SORT=generic_m_ai')
      order by NLSSORT(mycolumn, 'NLS_SORT=generic_m_ai')) as mygroupcolumn
  from (
    select case when aaa is null or length(aaa) = 0 then '(blank)' else aaa end
      || ' - ' || case when bbb is not null then bbb end as mycolumn
    from alex_collate_test
  )
)
group by mygroupcolumn
order by mygroupcolumn;

MYGROUPCOLUMN                                                 
---------------------------------------------------------------
HI - BYE                                                        
next - howdy                                                    

我还简化了(IMO)case结构,但也许这不是真正的结构。

添加一个数字列以进一步检查结果,假设您因某种原因进行分组,您的查询会获得:

MYCOLUMN                                                          SUM(CCC)
--------------------------------------------------------------- ----------
HI - BYE                                                                 8 
HI - bye                                                                 2 
hi - BYE                                                                 4 
hi - bye                                                                 1 
next - howdy                                                            16 

我的,通过调整从内部查询中获取ccc值:

select mygroupcolumn, sum(ccc)
from (
  select mycolumn, ccc, first_value(mycolumn)
    over (partition by NLSSORT(mycolumn, 'NLS_SORT=generic_m_ai')
      order by NLSSORT(mycolumn, 'NLS_SORT=generic_m_ai')) as mygroupcolumn
  from (
    select case when aaa is null or length(aaa) = 0 then '(blank)' else aaa end
      || ' - ' || case when bbb is not null then bbb end as mycolumn, ccc
    from alex_collate_test
  )
)
group by mygroupcolumn
order by mygroupcolumn;

......得到:

MYGROUPCOLUMN                                                     SUM(CCC)
--------------------------------------------------------------- ----------
HI - BYE                                                                15 
next - howdy                                                            16 

我确实似乎重新实现了MIN()。 @kordirko的回答更简单;使用相同的数据:

select min(mycolumn), sum(ccc)
from (
  select case when aaa is null or length(aaa) = 0 then '(blank)' else aaa end
    || ' - ' || case when bbb is not null then bbb end as mycolumn, ccc
  from alex_collate_test
)
group by NLSSORT(mycolumn, 'NLS_SORT=generic_m_ai')
order by NLSSORT(mycolumn, 'NLS_SORT=generic_m_ai');

MIN(MYCOLUMN)                                                     SUM(CCC)
--------------------------------------------------------------- ----------
HI - BYE                                                                15 
next - howdy                                                            16 

...所以除非你还需要其他分析结果,否则我可能会这样做。