#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