Oracle group by根据长度获取记录

时间:2016-10-18 20:07:05

标签: sql oracle

我在表格中分组后得到了这些数据,所以我们可以看到代码重复了 两次,因为有不同的名称与它相关联。

但是我希望每当最大长度超过那么得到那个名字,否则,得到短名称,

所以

  • cs161我需要Craig L Smith
  • cs226我需要C_SCHLASINGER

我以前获取以下数据的查询是

Select code, name, max(length(name)) 
from acct 
where code in ('CS226', 'CS161')
group by code,name

结果是:

CODE             MAX(LENGTH(T1.NAME))                      NAME
CS161                      7                               C SMITH
CS226                      13                              C SCHLASINGER
CS161                      13                              CRAIG L SMITH

任何帮助高度赞赏

2 个答案:

答案 0 :(得分:0)

只需将您的查询更改为:

select code, max(name) from acct
where
code in('CS226','CS161')
group by code

答案 1 :(得分:0)

要求有点不清楚......您可能有多个与“代码”关联的“名称”,并且您想选择最长的一个?如果有两个名称绑定相同的长度(对于相同的代码)怎么办?在任何情况下,您可能只想按代码分组(而不是代码和名称 - 根本不产生分组)。

这是一个基本的解决方案,如果有关系,选择相同(最大)长度的所有名称;如果只有一个名字最长的话,它只会选择最长的。

select code, name
from   acct a
where  length(name) = (select max(length(name)) from acct where code = a.code)
;

或者,使用GROUP BY和连接(而不是相关子查询):

select a.code, a.name
from   acct a inner join 
            (select code, max(length(name)) as max_len from acct group by code) b
              on a.code = b.code and length(a.name) = b.max_len
;

这是一个更先进的解决方案;对于给定的代码,它选择最长的名称,如果两个并列最长,则按字母顺序选择第一个。因此,在所有情况下,每个代码只返回一个名称。

select code, min(name) keep (dense_rank last order by length(name)) as name
from   acct
group by code
;

演示(两种方法):

with
     acct ( code, name ) as (
       select 'CS161', 'C SMITH'       from dual union all
       select 'CS226', 'C SCHLASINGER' from dual union all
       select 'CS161', 'CRAIG L SMITH' from dual union all
       select 'CS180', 'V HEUSE'       from dual union all
       select 'CS180', 'V HAUSE'       from dual
     )
select code, name
from   acct a
where  length(name) = (select max(length(name)) from acct where code = a.code)
;

CODE  NAME        
----- -------------
CS226 C SCHLASINGER
CS161 CRAIG L SMITH
CS180 V HEUSE      
CS180 V HAUSE

with
     acct ( code, name ) as (
       select 'CS161', 'C SMITH'       from dual union all
       select 'CS226', 'C SCHLASINGER' from dual union all
       select 'CS161', 'CRAIG L SMITH' from dual union all
       select 'CS180', 'V HEUSE'       from dual union all
       select 'CS180', 'V HAUSE'       from dual
     )
select code, min(name) keep (dense_rank last order by length(name)) as name
from   acct
group by code
; 

CODE  NAME        
----- -------------
CS161 CRAIG L SMITH
CS180 V HAUSE      
CS226 C SCHLASINGER