Специальное кодирование данных

Interloper
Дата: 30.09.2015 17:19:56
Имеется таблица с двумя полями: group_id integer и value varchar2. Может быть много разных значений value для одного значения
Требуется построить выборку, возвращающую для каждой записи group_id и минимальную подстроку (начиная с 1-го символа) из значения value, которая не совпадает с минимальными подстроками той же длины для других значений value с тем же group_id. Если такую минимальную подстроку выбрать нельзя - возвращать все значение value.
Выборка должна быть получена одним SQL-запросом.

Пример набора данных:
1 aaab
1 abbb
1 cddd
2 aabb
2 aa
2 abcd
2 bbcc

Выборка должна получиться такой:
1 aa
1 ab
1 c
2 aab
2 aa
2 ab
2 b
-2-
Дата: 30.09.2015 17:38:12
Interloper
не совпадает с минимальными подстроками той же длины
не понятно кто чей подстрока. судя по "2 aab" и
"2 aa", группировка в пределах длины полного value, то есть group_id и length(value).
Elic
Дата: 30.09.2015 17:46:36
case 1
  when count(*) over (partition by group_id, substr(value, 1, 1)) then substr(value, 1, 1)
  when count(*) over (partition by group_id, substr(value, 1, 2)) then substr(value, 1, 2)
  when count(*) over (partition by group_id, substr(value, 1, 3)) then substr(value, 1, 3)
  -- ...
  else value
end as non_common_value
SY
Дата: 30.09.2015 19:30:02
С учетом VALUE IS NOT NULL:

with r(
       id,
       val,
       sub_val,
       len,
       lvl,
       flag,
       rid
      ) as (
             select  id,
                     val,
                     substr(val,1,1) sub_val,
                     max(length(val)) over(partition by id) len,
                     1 lvl,
                     (
                      select  count(*)
                        from  tbl tbl2
                        where tbl1.id = tbl2.id
                          and substr(tbl1.val,1,1) = substr(tbl2.val,1,1)
                          and tbl1.rowid != tbl2.rowid
                          and rownum = 1
                     ) flag,
                     rowid rid
               from  tbl tbl1
            union all
             select  r.id,
                     r.val,
                     substr(r.val,1,r.lvl + 1) sub_val,
                     r.len,
                     r.lvl + 1,
                     (
                      select  count(*)
                        from  tbl
                        where r.id = tbl.id
                          and substr(r.val,1,r.lvl + 1) = substr(tbl.val,1,r.lvl + 1)
                          and r.rid != tbl.rowid
                          and rownum = 1
                     ) flag,
                     r.rid
               from  r
               where r.lvl != r.len
                 and flag = 1
           )
select  id,
        sub_val
  from  r
  where flag = 0
  order by id,
           sub_val
/

        ID SUB_
---------- ----
         1 aa
         1 ab
         1 c
         2 aa
         2 aab
         2 ab
         2 b

7 rows selected.

SQL> 


SY.