我们当前的应用程序允许通过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
答案 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
...所以除非你还需要其他分析结果,否则我可能会这样做。