1

我们当前的应用程序允许通过 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 的“整理”代码,并将列包装在“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
4

2 回答 2

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

于 2013-07-15T19:24:29.917 回答
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 

...所以除非您无论如何都需要其他分析结果,否则我可能会这样做。

于 2013-07-15T19:25:40.303 回答