Случай с ульями в результате повторяющейся строки - PullRequest
0 голосов
/ 02 октября 2018

У меня есть таблица с контактными номерами и другая справочная таблица, содержащая переменную длины и столбец с номерами.Мне нужно найти имя префикса, где префикс номера совпадает с префиксом в справочной таблице, но это должен быть тот, который соответствует самому длинному совпадению префикса.(О боже, я надеюсь, что это имеет смысл)

То, что я пробовал до сих пор:

select a.record_type,a.number,b.prefix,b.prefix_name 
from first_table a , second_table b 
where  a.transaction_date=20180924 and case  
    when b.length=1 then substr(a.number,1,1)=b.prefix  
    when b.length=2 then substr(a.number,1,2)=b.prefix  
    when b.length=3 then substr(a.number,1,3)=b.prefix  
    when b.length=4 then substr(a.number,1,4)=b.prefix  
    when b.length=5 then substr(a.number,1,5)=b.prefix  
    when b.length=6 then substr(a.number,1,6)=b.prefix  
    when b.length=7 then substr(a.number,1,7)=b.prefix  
    when b.length=8 then substr(a.number,1,8)=b.prefix 
    when b.length=9 then substr(a.number,1,9)=b.prefix 
    when b.length=10 then substr(a.number,1,10)=b.prefix 
    when b.length=11 then substr(a.number,1,11)=b.prefix 
    when b.length=12 then substr(a.number,1,12)=b.prefix 
    when b.length=13 then substr(a.number,1,13)=b.prefix 
    when b.length=14 then substr(a.number,1,14)=b.prefix 
end

Однако он по-прежнему возвращает повторяющийся результат, то есть: если число равно 12345, оно соответствует ссылкес префиксом 1234 и 123, а я на самом деле просто хочу 1234.

Есть ли способ как-то расставить приоритеты в кейсе?Спасибо

Пример данных в двух таблицах: пример

Мой текущий результат и желаемый результат: результаты

Ответы [ 2 ]

0 голосов
/ 02 октября 2018

Вы можете использовать row_number():

select ap.*
from (select a.record_type, a.number, p.prefix, p.prefix_name,
             row_number() over (partition by  a.record_type, a.number order by p.length desc) as seqnum
      from first_table a join
           second_table p
           on (p.length = 1 and substr(a.number, 1, 1) = p.prefix) and
              (p.length = 2 and substr(a.number, 1, 2) = p.prefix) and
              . . . 
              (p.length = 14 and substr(a.number, 1, 14) = p.prefix)    
      where a.transaction_date = 20180924 
     ) ap
where seqnum = 1;

Это можно выразить более кратко, как:

select ap.*
from (select a.record_type, a.number, p.prefix, p.prefix_name,
             row_number() over (partition by  a.record_type, a.number order by p.length desc) as seqnum
      from first_table a join
           second_table p
           on substr(a.number, 1, p.length) = p.prefix    
      where a.transaction_date = 20180924 
     ) ap
where seqnum = 1;

Другой метод выполняет сравнения с использованием отдельных join с и останавливается напервый матч:

select a.record_type, a.number,
       coalesce(p14.prefix, p13.prefix, . . . , p1.prefix) as prefix,
       coalesce(p14.prefix_name, p13.prefix_name, . . . , p1.prefix_name) as prefix_name
from first_table a left join
     second_table p14
     on p14.length = 14 and substr(a.number, 1, 14) = p14.prefix left join
     second_table p13
     on p13.length = 13 and substr(a.number, 1, 13) = p13.prefix and p14.prefix is null left join
     second_table p12
     on p12.length = 12 and substr(a.number, 1, 12) = p12.prefix and p13.prefix is null left join
     . . .
     second_table p1
     on p1.length = 1 and substr(a.number, 1, 1) = p1.prefix and p2.prefix is null 
0 голосов
/ 02 октября 2018

Хорошо, я переделал, попробуйте это:

    WITH FIRST_TABLE (RECORD_TYPE,NUM,TRANSACTION_DATE)AS (
    SELECT 'a',12345, DATE '2018-09-24' FROM DUAL
    ),
    SECOND_TABLE (PREFIX,PREFIX_NAME,LENGTH) AS(
    SELECT 12,'Type A', 2 FROM DUAL union all
    SELECT 1234,'Type B', 4 FROM DUAL 
    )
    select * from (
    SELECT A.RECORD_TYPE,A.NUM,B.PREFIX,B.PREFIX_NAME, MAX(B.PREFIX) OVER (PARTITION BY A.RECORD_TYPE,A.NUM) maxPrefix
    FROM FIRST_TABLE A ,SECOND_TABLE B
    WHERE  A.TRANSACTION_DATE=DATE '2018-09-24' 
    AND A.NUM LIKE (B.PREFIX||'%')
    )
    where PREFIX=maxPrefix;
...