2016-07-18 3 views
1

Я делаю проект, чтобы найти список парных левых частей в таблице. Таблица содержит столбец уникальных идентификаторов деталей и столбец атрибутов «Влево» или «Вправо».Oracle SQL Найти последовательные значения, основанные на критериях в другом столбце

Если в таблице есть правая левая пара, то слева будет отображаться один уникальный идентификатор детали до правой (ID 4 будет левым, а идентификатор 5 будет справа). Тем не менее, есть много уникальных идентификаторов между каждой левой правой парой, у которых нет пары. Я пытаюсь написать запрос, чтобы найти все пары Left и Right в таблице.

Например (в настоящее время оба ID и LR являются VARCHAR2)

ID LR 
1 L 
2 R 
5 R 
9 R 
22 R 
34 L 
35 R 
38 L 
91 L 
92 R 

и мне нужен запрос, возвращающий

ID LR 
1 L 
2 R 
34 L 
35 R 
91 L 
92 R 

Моя текущая строка мышления является условным запрос, чтобы выбрать все идентификаторы и LR, когда LR есть R, существует ID-1 и что LR есть L, но я не уверен ... любая помощь будет принята с благодарностью! Спасибо.

ответ

0

Операции по установке - это один из способов, которыми вы могли бы это сделать.

(отредактированный переписать запрос в соответствии с комментариев - теперь он обрабатывает ведущие нули в поле VARCHAR ID)


WITH matches AS (
    SELECT to_number(ID) AS ID_integer 
    FROM base_table 
    WHERE LR = 'L' 
    INTERSECT 
    SELECT to_number(ID)-1 
    FROM base_table 
    WHERE LR = 'R' 
) 
SELECT bt.ID, bt.LR, m.ID_integer 
FROM base_table bt, matches m 
WHERE LR = 'L' 
AND to_number(bt.ID) = m.ID_integer 
UNION 
SELECT bt.ID, bt.LR, m.ID_integer 
FROM base_table bt, matches m 
WHERE LR = 'R' 
AND to_number(bt.ID)-1 = m.ID_integer 
ORDER BY 3, 2; 
+0

Это не будет работать - вы заметили, что идентификаторы не являются последовательной последовательностью ? Следующий идентификатор после 2 равен 5, а не 3. – mathguy

+0

@mathguy, я просто протестировал его, и он работает так, как должен. –

+0

Измените id 2 так, чтобы он был 3 вместо 2 (с lr = R) и оставил все остальное одинаковым, посмотрите, работает ли запрос. – mathguy

0
with inputs (id, lr) as (
     select 1, 'L' from dual union all 
     select 2, 'R' from dual union all 
     select 5, 'R' from dual union all 
     select 9, 'R' from dual union all 
     select 22, 'R' from dual union all 
     select 34, 'L' from dual union all 
     select 35, 'R' from dual union all 
     select 38, 'L' from dual union all 
     select 91, 'L' from dual union all 
     select 92, 'R' from dual 
    ), 
    prep (id, lr, prev_lr, next_lr) as (
     select id, lr, lag(lr) over (order by id), lead(lr) over (order by id) 
     from inputs 
    ) 
select id, lr 
from  prep 
where (lr = 'L' and next_lr = 'R') or (lr = 'R' and prev_lr = 'L') 
order by id 
; 


     ID L 
---------- - 
     1 L 
     2 R 
     34 L 
     35 R 
     91 L 
     92 R