Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 разбросать данные  [new]
Ф.Мягков
Guest
допустим есть таблица на 20 миллионов строк типа:
id number, nop number, ndate varchar2  (формат данных вида MMDDHH24)
необходимо выбрать четверть данных с сортировкой по ndate, причем 2 одинаковых номера nop не могут идти подряд. Есть решение используя row_number, но это ресурсоемко, может есть решение проще?
16 авг 07, 18:05    [4537084]     Ответить | Цитировать Сообщить модератору
 Re: разбросать данные  [new]
Elic
Member

Откуда:
Сообщений: 29980
Lag-фильтрацию можно осуществить в pipelined-функции.
16 авг 07, 18:21    [4537200]     Ответить | Цитировать Сообщить модератору
 Re: разбросать данные  [new]
Ф.Мягков
Guest
Elic
Lag-фильтрацию можно осуществить в pipelined-функции.

чуть подробнее, как при этом не пропустить дынные?
16 авг 07, 18:33    [4537265]     Ответить | Цитировать Сообщить модератору
 Re: разбросать данные  [new]
Elic
Member

Откуда:
Сообщений: 29980
Ф.Мягков
Elic
Lag-фильтрацию можно осуществить в pipelined-функции.
чуть подробнее, как при этом не пропустить дынные?
А вроде нужно пропустить повторяющиеся :)
16 авг 07, 18:45    [4537315]     Ответить | Цитировать Сообщить модератору
 Re: разбросать данные  [new]
Jannny
Member

Откуда: Спб
Сообщений: 6424
А что делать, если они все-таки получаются подряд, то бишь 5 и более значений подряд при сортировке по дате, как правильно четверть определить?
Например, отсортированные по дате выглядят так:

11 подряд "единиц" и "двойка"

Как должна выглядеть четверть?
16 авг 07, 19:11    [4537385]     Ответить | Цитировать Сообщить модератору
 Re: разбросать данные  [new]
Elic
Member

Откуда:
Сообщений: 29980
select count(*)/4 into fCnt ...
for c in (select ... order by ...) loop
  if fLastNop is null or c.nop <> fLastNop then
    pipe row ...
    fCnt := fCnt - 1;
    exit when fCnt <= 0;
    fLastNop := c.nop;
  end if;
end loop;
? :)

Jannny
Как должна выглядеть четверть?
Знать не судьба :)
16 авг 07, 19:26    [4537420]     Ответить | Цитировать Сообщить модератору
 Re: разбросать данные  [new]
Jannny
Member

Откуда: Спб
Сообщений: 6424
Я чисто поигралась :) Про быстроту тут речи не стоит, как собственно и в принципе для аналитики на 20 миллионов :)
Кстати поскольку читать задание можно по-разному, сформулирую свое понимание:
поделить на 4 части, вернуть четверть, при этом если идут подряд одинаковые значения в порядке даты, то подменить строку другим вариантом.

with t as (
select 1 id, sysdate dd from dual union all
select 2 id, sysdate+2 dd from dual union all
select 3 id, sysdate+3 dd from dual union all
select 3 id, sysdate+4 dd from dual union all
select 5 id, sysdate+5 dd from dual union all
select 6 id, sysdate+6 dd from dual union all
select 7 id, sysdate+7 dd from dual union all
select 8 id, sysdate+8 dd from dual union all
select 9 id, sysdate+9 dd from dual union all
select 10 id, sysdate+10 dd from dual union all
select 10 id, sysdate+11 dd from dual union all
select 12 id, sysdate+12 dd from dual union all
select 13 id, sysdate+13 dd from dual
)
select * 
from (
  select t.*, count(decode(rn, 1, l)) over () cou, row_number() over (partition by rn order by dd) rn2
  from (
    select t.*, 
           ntile(4) over (order by 1) rn,
           decode(id, lag(id) over (order by dd), 1) l
    from t
  ) t
)
where rn = 1 and l is null or (rn = 2 and l is null and rn2 <= cou)
order by dd


ЗЫ: Учитывая мой предыдущий вопрос, в моем варианте получится только одна единица и одна двойка.
16 авг 07, 19:27    [4537421]     Ответить | Цитировать Сообщить модератору
 Re: разбросать данные  [new]
Jannny
Member

Откуда: Спб
Сообщений: 6424
Jannny
блин, опечатка:
with t as (
select 1 id, sysdate dd from dual union all
select 2 id, sysdate+2 dd from dual union all
select 3 id, sysdate+3 dd from dual union all
select 3 id, sysdate+4 dd from dual union all
select 5 id, sysdate+5 dd from dual union all
select 6 id, sysdate+6 dd from dual union all
select 7 id, sysdate+7 dd from dual union all
select 8 id, sysdate+8 dd from dual union all
select 9 id, sysdate+9 dd from dual union all
select 10 id, sysdate+10 dd from dual union all
select 10 id, sysdate+11 dd from dual union all
select 12 id, sysdate+12 dd from dual union all
select 13 id, sysdate+13 dd from dual
)
select * 
from (
  select t.*, count(decode(rn, 1, l)) over () cou, row_number() over (partition by rn order by dd) rn2
  from (
    select t.*, 
           ntile(4) over (order by dd) rn,
           decode(id, lag(id) over (order by dd), 1) l
    from t
  ) t
)
where rn = 1 and l is null or (rn = 2 and l is null and rn2 <= cou)
order by dd
16 авг 07, 19:28    [4537423]     Ответить | Цитировать Сообщить модератору
 Re: разбросать данные  [new]
Ф.Мягков
Guest
Не пропускать, а смешать надо:
Исходные:
1    1    081600
2    1    081600
3    3    081600
4    1    081600
5    2    081601

Результат:
1    1    081600
3    3    081600 
2    1    081600 
4    1    081600
5    2    081601
2 и 4 в конце можно поменять местами так как других вариантов уже нет
16 авг 07, 19:36    [4537442]     Ответить | Цитировать Сообщить модератору
 Re: разбросать данные  [new]
Ф.Мягков
Guest
забыл дополнительную деталь упомянуть, если других значений не остается, то подряд допустимы значения
16 авг 07, 19:41    [4537449]     Ответить | Цитировать Сообщить модератору
 Re: разбросать данные  [new]
Jannny
Member

Откуда: Спб
Сообщений: 6424
Ф.Мягков
Не пропускать, а смешать надо
Что-то после Ваших последних объяснений мне стало менее ясно. То бишь отбираем сразу четверть (остальное отбрасываем), а потом эту четверть просто пересортировываем, так что ли?
16 авг 07, 19:42    [4537450]     Ответить | Цитировать Сообщить модератору
 Re: разбросать данные  [new]
Ф.Мягков
Guest
Ф.Мягков
Не пропускать, а смешать надо:
Исходные:
1    1    081600
2    1    081600
3    3    081600
4    1    081600
5    2    081601

Результат:
1    1    081600
3    3    081600 
2    1    081600 
4    1    081600
5    2    081601
2 и 4 в конце можно поменять местами так как других вариантов уже нет

и от результата взять четверть забыл
16 авг 07, 19:45    [4537453]     Ответить | Цитировать Сообщить модератору
 Re: разбросать данные  [new]
Elic
Member

Откуда:
Сообщений: 29980
Ф.Мягков
Не пропускать, а смешать надо:
Правильно заданный вопрос - это половина ответа. В твоём случае - гораздо больше
where четверть
order by ndate, row_number() over (partition by ndate, nop order by id), id
16 авг 07, 19:48    [4537455]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить