2015-05-29 2 views
-1

Образец данных:Oracle запрос с Partision, ордена и Bucketing

Customer ID Transaction Date Code Expected Bucketing 
----------- ---------------- ---- ---- 
      1 1/1/2015  254  1 
      1 1/2/2015  253  1 
      1 1/13/2015  271  1 
      1 1/14/2015  271  1 
      1 2/1/2015  254  2 
      1 2/12/2015  253  2 
      1 2/13/2015  271  2 
      1 3/1/2015  254  3 
      1 3/12/2015  253  3 
      1 3/13/2015  271  3 
      2 1/1/2015  254  1 
      2 1/2/2015  253  1 
      2 1/13/2015  271  1 
      2 1/14/2015  271  1 
      2 2/1/2015  254  2 
      2 2/12/2015  253  2 
      2 2/13/2015  271  2 

Я хочу Partision от «ID клиента» и выберите пункт «Дата транзакции» EVERYTIME первая запись начинается с кодом транзакции 254. I должен начать отсчет первый раз, когда я нашел 254 (1), пока не найдет следующие 254 (тогда их число равно 2). 4-е поле - это то, чего я пытаюсь достичь.

Может кто-то помочь мне с этим в запросе Oracle, чтобы получить данные, такие как поле 4 выше

Благодаря

ответ

1

Решение - автообъединение запрос, в котором один из подзапросов представляет собой данные с кодом = 254, второй - отдых. Эти подзапросы рядом присоединились и номера строк из первого присваиваются второй части:

with t1 as (
    select cid, tdate td1, code, 
     lead(tdate) over (partition by cid order by tdate) td2, 
     row_number() over (partition by cid order by tdate) rn 
     from test where code=254), 
    t2 as (select cid, tdate, code from test where code<>254) 
select t2.cid, t2.tdate, t2.code, t1.rn from t1 
    join t2 on t1.cid = t2.cid 
     and t2.tdate between nvl(t1.td1, t2.tdate) and nvl(t1.td2, t2.tdate) 
union all 
select cid, td1, code, rn from t1 order by cid, tdate 

SQLFiddle demo


Solution - рекурсивный запрос, доступный от Oracle версии 11g:

with t as (select cid, tdate, code, 
    row_number() over (partition by cid order by tdate) rn from test), 
u (cid, td, cd, rn, x) as (
    select cid, tdate, code, rn, 1 from t where rn=1 
    union all 
    select t.cid, t.tdate, t.code, t.rn, decode(t.code, 254, u.x+1, u.x) 
    from u join t on t.cid = u.cid and t.rn = u.rn+1) 
select cid, td, cd, x from u order by cid, td 

SQLFiddle demo


Оба решения дали желаемый результат, и в обоих случаях я предположил, что строка с кодом = 254 сначала устанавливается для каждого клиента, как в вашем примере.

Полезные ссылки: function lead(), функция row_number(), recursive queries и, наконец, How do I ask a good question?.

Смежные вопросы