Oracle SQL — сравнение повторяющихся значений

#sql #oracle #duplicates #comparison

#sql #Oracle #дубликаты #сравнение

Вопрос:

У меня есть таблица с диапазоном полей, которая имеет значения следующим образом:

 102453
104953-256454
  

Значения могут быть одним 6-значным числом или двумя 6-значными числами, разделенными тире.

Пользователь вводит значение (либо 6-значное число, либо два 6-значных числа, разделенных тире), и значение должно быть сравнено с существующими значениями в базе данных.

  • если введенное значение представляет собой 6-значное число, то его следует сравнить со всеми одиночными 6-значными значениями в базе данных, а также с отдельными 6-значными значениями, хранящимися в виде 2-значных значений, разделенных символом (-)
  • если введенное значение представляет собой два 6-значных числа, то оно должно быть проанализировано, и каждое значение должно сравниваться с каждым значением в базе данных.

Как мне это сделать?

Комментарии:

1. Вместо этого используйте два отдельных столбца. (Если вы не можете изменить таблицу, вы можете использовать представление, производную таблицу или cte.)

2. К сожалению, это дизайн клиента.

3. Вы можете использовать REGEXP_SUBSTR(ы, ‘[^-] ‘, 1, 1) и REGEXP_SUBSTR(ы, ‘[^-] ‘, 1, 2) чтобы получить оба 6-значных значения из входных данных и использовать их с помощью оператора LIKE.

Ответ №1:

Я предполагаю, что есть какое-то поле идентификатора (я надеюсь).

 with Dumbassery as
(
select id, 'Single' as NumType, substr(MyField,1,6) as Num1, '' as Num2
from MyTable
where length(MyField) = 6
union
select id, 'Range' as NumType, substr(MyField,1,6) as Num1, substr(MyField,8,6) as Num2
from MyTable
where length(MyField) = 13
)

, Filter1 as
(
select id,
       case
           when exists (select 1 from Dumbassery D2 where D1.Num1 between D2.Num1 and D2.Num2 and D2.NumType = 'Range') then 'Exists'
           when exists (select 1 from Dumbassery D2 where D2.NumType = 'Single' and D1.Num1 = D2.Num1) then 'Exists'
           else 'New'
       end as NumExist
from Dumbassery D1
where D1.NumType = 'Single'

union

select id,
       case
           when exists (select 1 from Dumbassery D2 where D1.Num1 between D2.Num1 and D2.Num2 and D2.NumType = 'Range') then 'Exists'
           when exists (select 1 from Dumbassery D2 where D1.Num2 between D2.Num1 and D2.Num2 and D2.NumType = 'Range') then 'Exists'
           when exists (select 1 from Dumbassery D2 where D2.Num2 between D1.Num1 and D1.Num2 and D2.NumType = 'Single') then 'Exists'
           else 'New'
       end as NumExist
from Dumbassery D1
where D1.NumType = 'Range'
)

select distinct *
from Filter1
where NumExist = 'New'
  

Ответ №2:

Поскольку вы указываете диапазон с именем, я думаю, вам нужно найти пересечения с новым диапазоном. Я добавляю таблицу test_val для проверки некоторых вариантов new_range .

  WITH
 table_ranges AS /*is table with ranges*/
 (select '123212' as range from dual union all
  select '123214-223214' as range from dual union all 
  select '123900-987121' as range from dual )
 ,test_val as /*is table with test values*/
 (select '123212' as test_range from dual union all 
  select '123213' as test_range from dual union all 
  select '123215' as test_range from dual union all 
  select '123213-123290' as test_range from dual union all 
  select '124000-125000' as test_range from dual union all 
  select '987000-987124' as test_range from dual union all 
  select '987122-987124' as test_range from dual ) 
  select CAse WHEN EXISTS (select null
                             from table_ranges 
                        where substr(t.test_range,  1,6) between substr(range, 1,6) and substr(range, -6,6) 
                           or substr(t.test_range, -6,6) between substr(range, 1,6) and substr(range, -6,6) ) 
              THEN 'already exists' 
              ELSE'intersection not found' 
            END AS test_status 
   FROM test_val t