Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Помогите написать запрос  [new]
янковский
Guest
Cреди идентификаторов моделей в таблице PC(id integer, model varchar(32)) имеются пропуски. Надо найти минимальный и максимальный "свободный" идентификатор в диапазоне между имеющимися максимальным и минимальным идентификаторами в таблице PC.
Если пропусков нет, выводить NULL.
Например, для последовательности идентификаторов моделей 1,2,5,7 результат должен быть 3 и 6
15 фев 08, 13:19    [5294613]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116274
Мой вариант будет не только самым первым, но и безусловно самым
примитивным

SQL> with tab1 as
  2  (select 1 col1 from dual
  3  union all
  4  select 2 col1 from dual
  5  union all
  6  select 5 col1 from dual
  7  union all
  8  select 7 col1 from dual
  9  ),
 10  tab2 as
 11  (select level lv from dual
 12  connect by level <= (select max(col1) from tab1) -
 13                       (select min(col1) from tab1) + 1)
 14  select min(lv), max(lv) from tab2 where lv not in (select col1 from tab1)
 15  /
 
   MIN(LV)    MAX(LV)
---------- ----------
         3          6
 
SQL> 
15 фев 08, 13:27    [5294689]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
типа этого что-то
with t as (select 1 n from dual
     union select 2 from dual
     union select 5 from dual
     union select 7 from dual
     union select 9 from dual
) ,t2 as (select n
        ,+n-lag(n) over (order by n) la
        ,-n+lead(n) over (order by n) le
         from t)
      select max(n)-1 from t2 where la>1
union select min(n)+1 from t2 where le>1
15 фев 08, 13:33    [5294741]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
Madness
Member

Откуда: Москва
Сообщений: 648
SQL> with t as
  2  (
  3            select 1 n from dual
  4  union all select 2 n from dual
  5  union all select 5 n from dual
  6  union all select 7 n from dual
  7  )
  8  select min(r), max(r)
  9    from (select n, case when n - lag(n) over (order by n) > 1 then lag(n) over (order by n) + 1 end r from t)
 10   where r is not null
 11  /
 
    MIN(R)     MAX(R)
---------- ----------
         3          6
15 фев 08, 13:33    [5294750]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
Elic
Member

Откуда:
Сообщений: 29990
янковский
для 1,2,5,7 результат должен быть 3 и 6
А для 1,2,5,7,11,12? :)
15 фев 08, 13:52    [5294908]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
Янковский
Guest
Elic
янковский
для 1,2,5,7 результат должен быть 3 и 6
А для 1,2,5,7,11,12? :)


3 и 10, как мне кажется :-)
15 фев 08, 13:54    [5294937]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
RA\/EN
Member

Откуда:
Сообщений: 3659
"Скоростной вариант". который я сам когда-то ожидал услышать от кандидатов (при наличии PK):
SQL> create table PC(id primary key, model ) as select level,lpad('z',32,'z') from dual connect by level <=1e5;
 
Table created
 
SQL> delete pc where id in (5,1e5-5);
 
2 rows deleted
 
SQL> commit;
 
Commit complete
 
SQL> set timing on
SQL> 
SQL> WITH q AS (SELECT 1 s,1e5 e
  2               FROM dual)
  3  SELECT (SELECT *
  4            FROM (SELECT p1.id+1
  5                    FROM q,pc p1
  6                   WHERE p1.id > q.s
  7                     AND NOT EXISTS (SELECT 1 FROM pc p2 WHERE p2.id = p1.id+1))
  8           WHERE ROWNUM <=1) minfreeid,
  9         (SELECT *
 10            FROM (SELECT /*+index_desc(p1)*/p1.id-1
 11                    FROM q,pc p1
 12                   WHERE p1.id < q.e
 13                     AND NOT EXISTS (SELECT 1 FROM pc p2 WHERE p2.id = p1.id-1)
 14                   ORDER BY p1.id DESC)
 15           WHERE ROWNUM <=1) maxfreeid
 16    FROM dual
 17  /
 
 MINFREEID  MAXFREEID
---------- ----------
         5      99995
 
Executed in 0,04 seconds
 
SQL> 
P.S. Вариант комрада Dmidek-а не отработал - когда не должался за минуту, пригляделся повнимательней и ...
15 фев 08, 14:02    [5295016]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
privet
Member

Откуда:
Сообщений: 52
with t as
    (
              select 1 n from dual
    union all select 2 n from dual
    union all select 5 n from dual
    union all select 8 n from dual
    union all select 7 n from dual
    union all select 9 n from dual
    union all select 11 n from dual
    union all select 13 n from dual
    )
    select min(n+1),max(n-1)
      from t tt
    where tt.n+1 not in(select t.n from t
                  )
тоже примитивный)
15 фев 08, 14:11    [5295110]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
Aleks-ek
Member

Откуда:
Сообщений: 85
privet
with t as
    (
              select 1 n from dual
    union all select 2 n from dual
    union all select 5 n from dual
    union all select 8 n from dual
    union all select 7 n from dual
    union all select 9 n from dual
    union all select 11 n from dual
    union all select 13 n from dual
    )
    select min(n+1),max(n-1)
      from t tt
    where tt.n+1 not in(select t.n from t
                  )
тоже примитивный)

И неправильный , помедитируй с 1,2,3
15 фев 08, 15:06    [5295725]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116274
RA\/EN

P.S. Вариант комрада Dmidek-а не отработал - когда не должался за минуту, пригляделся повнимательней и ...


Ну вот, взяли мой простенький запросик и под нагрузку его
Ну ладно, вроде что то сделать еще можно ... :-)

SQL> set timing on
SQL> with tab1 as
  2  (select 1 col1 from dual
  3  union all
  4  select 2 col1 from dual
  5  union all
  6  select 5 col1 from dual
  7  union all
  8  select 1e5 col1 from dual
  9  ),
 10  tab2 as
 11  (select level lv from dual
 12  connect by level <= (select max(col1) from tab1) -
 13                       (select min(col1) from tab1) + 1)
 14  select min(lv), max(lv)
 15  from tab2 left join tab1
 16  on (lv = col1)
 17  where col1 is null
 18  /

   MIN(LV)    MAX(LV)
---------- ----------
         3      99999

Abgelaufen: 00:00:01.74
SQL>
15 фев 08, 15:16    [5295817]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
Xakpe
Guest
select min(a.q_id), max(a.q_id) from (select q_id + 1 as q_id from utQ union select q_id - 1 as q_id from utQ) a where a.q_id not in (select q_id from utQ) and a.q_id between (select min(q_id) from utQ) and (select max(q_id) from utQ)
18 фев 08, 01:36    [5301659]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
Тифа
Guest
можно пивот какойнить пикрутить минусом
18 фев 08, 07:07    [5301725]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
Authors
Member

Откуда: Харьков
Сообщений: 127
Если вы сами не можете решить столь простую задачу зачем вы ввязались в прохождение теста???
Ваш сертификат ничего не будет стоить - это всего лишь бумажка! Учитесь решать задания сами!
18 фев 08, 08:57    [5301814]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить