Oracle 尝试按通用的m_ai进行分组

Oracle 尝试按通用的m_ai进行分组,oracle,oracle11g,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 i

我们当前的应用程序允许通过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的“Collate”代码,并将列包装为“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
也许使用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 FIDLE的链接:

提供用于使用该值执行排序的字节,它是一个
原始值。所以它不是直接有用的

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

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)的
案例
结构,但对于您的真实案例,这可能不是那么简单

添加一个数字列以进一步检查结果,假设您分组的原因是,您的查询将得到:

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()
,有点像@科迪尔科的答案更简单;同样的数据也给出:

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 
。。。所以我可能会同意,除非你需要其他的分析结果