Нахождение определенного числа на основе существующего числа в таблице - PullRequest
0 голосов
/ 17 апреля 2020

Я не могу найти решение для моей проблемы ... например, у меня есть список кодов и тарифов, связанных с такими кодами, как,

create table a (codes number, rate number);
insert into a values (123, 0.23);
insert into a values (12334, 0.33);
insert into a values (12456, 0.23);
insert into a values (2234, 0.13);
commit;

Я хочу, чтобы были выбраны только эти коды например, здесь указаны ставки для родительских кодов, здесь я хочу код 12334, поскольку у нас в качестве родительского кода 123.

Пожалуйста, предложите несколько указателей, если не точный ответ.

Спасибо.

Ответы [ 5 ]

0 голосов
/ 17 апреля 2020

Нет необходимости конвертировать в VARCHAR2 для вашей числовой модели (хотя, как указывалось другими, вы можете добиться лучших и стабильных результатов с помощью явного смоделированного столбца parent_id).

Чтобы получить все строки с прямым или косвенным родителем используют этот запрос

select par.codes parent_codes, cld.codes, cld.rate
from a par 
 join a cld 
 on par.codes < cld.codes and
 par.codes = trunc(cld.codes / power(10,ceil(log(10,cld.CODES)) - ceil(log(10,par.CODES))))


PARENT_CODES      CODES       RATE
------------ ---------- ----------
         123      12334 ,33       

Обратите внимание, что ceil(log(10,cld.CODES)) - это число цифр в коде. Вы вычисляете разницу в количестве цифр между дочерним кодом и родительским кодом и получаете power из 10.

Это дает, например, 100 для 12345 и 123.

Результат используется для разделения дочернего кода, и вся часть деления (после trunc) сравнивается с родительским кодом. Если они совпадают, у дочернего кода есть родитель.

Вы также можете рассмотреть этот расчет как технико-экономическое обоснование вашей модели

0 голосов
/ 17 апреля 2020

Это даст ожидаемый результат

  select * from a a1
  where  exists (select 1 from a a2 
  where instr(a1.codes,a2.codes) =1 
  and length(a1.codes) >  length(a2.codes));
0 голосов
/ 17 апреля 2020

Держитесь подальше от так называемых «умных» клавиш, где вы должны знать скрытое значение. Разбейте компоненты на их собственные атрибуты. Таким образом, данные понятны, а то, что вы хотите, легко выбирается. Избегайте путаницы "Является ли код родительским или дочерним? Является ли 12456 дочерней строкой, в которой отсутствует родительская строка, или родительской?

create table a (main_code number, sub_code number, rate number);
insert into a values (123,   null, 0.23);
insert into a values (123,   34,   0.33);
insert into a values (12456, null, 0.23);
insert into a values (2234,  null, 0.13);
0 голосов
/ 17 апреля 2020

Вы можете превратить число в строки для сравнения и использовать exists:

select a.*
from a
where exists (
    select 1 
    from a a1 
    where a1.codes <> a.codes and a.codes like a1.codes || '%'
)

Как прокомментировал mathguy, это можно упростить как:

select a.*
from a
where exists (
    select 1 
    from a a1 
    where a.codes like a1.codes || '_%'
)

Метасимвол '_' заставляет a.codes иметь как минимум на один символ больше, чем a1.codes, что исключает необходимость проверки неравенства.

0 голосов
/ 17 апреля 2020

Вы можете использовать exists следующим образом

SELECT * FROM YOUR_TABLE T
WHERE EXISTS 
     (SELECT 1 FROM YOUR_TABLE TIN
      WHERE INSTR(T.CODES,TIN.CODES) = 1
      AND T.CODES <> TIN.CODES)
...