2016-10-18 4 views
0

У меня есть эти данные после группировки по таблице, поэтому мы можем видеть, что код повторяется дважды, поскольку с ним связаны разные имена.Группа 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 

Любая помощь высоко оценили

ответ

0

Требование немного неясно ... Вы можете иметь более одного «имени», связанного с «кодом», и вы хотите выбрать самый длинный? Что, если есть два имени, привязанных к одной и той же длине (для одного и того же кода)? В любом случае вы, вероятно, должны группироваться по одному коду (а не по коду AND name), который вообще не создает группировку).

Это элементарное решение, которое выбирает все имена одной и той же (наибольшей) длины, если есть связи; иначе он просто выбирает самый длинный, если есть только один с самым длинным именем.

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 
; 

Demo (для обоих подходов):

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 
0

Просто измените запрос:

select code, max(name) from acct 
where 
code in('CS226','CS161') 
group by code 
Смежные вопросы