Каков хороший подход в MS SQL Server 2008, чтобы присоединиться к «лучшему» совпадению? - PullRequest
2 голосов
/ 14 сентября 2010

По сути, я хочу выбрать наилучшее совпадение префикса из таблицы «Тариф» на основе поля «Телефонный номер» в таблице «Звонок».Учитывая приведенные ниже примеры данных, «0123456789» лучше всего соответствует префиксу «012», а «0100000000» лучше всего соответствует префиксу «01».

Я включил несколько DML с некоторыми другими примерами правильных совпаденийкомментарии SQL.

В таблице тарифов будет около 70000 строк, а в таблице вызовов будет около 20 миллионов строк.Но для таблицы «Выбрать из вызова» будет установлено ограничение на основе столбца dateTime, поэтому на самом деле для запроса потребуется только более 0,5 млн. Строк вызова.

Префикс в таблице тарифов может быть до 16персонажи длинные.

Я понятия не имею, как подойти к этому в SQL, сейчас я думаю о написании функции C # SQLCLR для этого.Кто-нибудь делал что-нибудь подобное?Буду признателен за любые ваши советы.

Пример данных

Таблица вызовов:

Id  TelephoneNumber
1   0123456789
2   0100000000
3   0200000000
4   0780000000
5   0784000000
6   0987654321

Таблица тарифов:

Prefix Scale
       1
01   1.1
012 1.2
02   2
078    3
0784   3.1

DML

create table Rate
(
    Prefix nvarchar(16) not null,
    Scale float not null
)

create table [Call]
(
    Id bigint not null,
    TelephoneNumber nvarchar(16) not null
)

insert into Rate (Prefix, Scale) values ('', 1)
insert into Rate (Prefix, Scale) values ('01', 1.1)
insert into Rate (Prefix, Scale) values ('012', 1.2)
insert into Rate (Prefix, Scale) values ('02', 2)
insert into Rate (Prefix, Scale) values ('078', 3)
insert into Rate (Prefix, Scale) values ('0784', 3.1)

insert into [Call] (Id, TelephoneNumber) values (1, '0123456789') --match 1.2
insert into [Call] (Id, TelephoneNumber) values (2, '0100000000') --match 1.1
insert into [Call] (Id, TelephoneNumber) values (3, '0200000000') --match 2
insert into [Call] (Id, TelephoneNumber) values (4, '0780000000') --match 3
insert into [Call] (Id, TelephoneNumber) values (5, '0784000000') --match 3.1
insert into [Call] (Id, TelephoneNumber) values (6, '0987654321') --match 1

Примечание: последний '0987654321' соответствует пустой строке, потому что более подходящих совпадений нет.

Ответы [ 4 ]

1 голос
/ 14 сентября 2010
SELECT t.Id, t.TelephoneNumber, t.Prefix, t.Scale
FROM
(
    SELECT *, ROW_NUMBER() OVER
              (
                  PARTITION BY c.TelephoneNumber
                  ORDER BY r.Scale DESC
              ) AS RowNumber
    FROM [call] AS c
        INNER JOIN [rate] AS r
            ON c.TelephoneNumber LIKE r.Prefix + '%'
) AS t
WHERE t.RowNumber = 1
ORDER BY t.Id
1 голос
/ 14 сентября 2010

Поскольку это основано на частичном сопоставлении, подвыбор будет единственно возможным вариантом (если, как предполагает LukeH, каждый вызов не уникален)

select
    c.Id,
    c.TelephoneNumber,
    (select top 1 
         Scale 

         from Rate r 

         where c.TelephoneNumber like r.Prefix + '%' order by Scale desc
    ) as Scale

from Call c
0 голосов
/ 14 сентября 2010

Вы можете использовать левое соединение, чтобы попытаться найти «лучшее» совпадение, а затем исключить такие совпадения в предложении where. e.g.:

select
 *
from
 Call c
  inner join
 Rate r
  on
   r.Prefix = SUBSTRING(c.TelephoneNumber,1,LEN(r.Prefix))
  left join
 Rate r_anti
  on
   r_anti.Prefix = SUBSTRING(c.TelephoneNumber,1,LEN(r_anti.Prefix)) and
   LEN(r_anti.Prefix) > LEN(r.Prefix)
where
 r_anti.Prefix is null
0 голосов
/ 14 сентября 2010

Попробуйте это:

select Prefix, min(c.TelephoneNumber)
from Rate r
left outer join Call c on c.TelephoneNumber like left(Prefix + '0000000000', 10) 
    or c.TelephoneNumber like Prefix + '%'
group by Prefix
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...