2017-01-15 2 views
1
 
ID | Company | Type 
--- | -------- | ---- 
1 | *  | * 
2 | CMP1  | * 
3 | CMP1  | TYP1 
4 | *  | TYP1 
5 | *  | TYP2 
6 | CMP1  | TYP2 

(Здесь компания и тип вместе делает первичный ключ.)Как получить наилучший результат соответствия из таблицы ниже?

Я должен получить точное совпадение с этой таблицей. Мои разные входы:

 
Company | Type | OutPut 
----- | ----- | ------- 
CMP1  | TYP1 | 3 
CMP2  | TYP2 | 5 
CMP5  | TYP5 | 1 
Если компания согласна с любой записью, то получите в противном случае * значение. Как вы это понимаете?

(В настоящее время я делал петлю в каждом поле и назначал оценку по лучшим совпадениям, а после этого я получаю первое значение по результату). Есть ли простой способ?

+0

В вашем примере отсутствует случай. Что произойдет, если есть одна строка с точным совпадением в компании и подстановочный знак по типу, а другая с точным соответствием по типу и подстановочному совпадению на компании? Что будет считаться «лучшим матчем»? –

+0

Да, спасибо за комментарий, В моем случае я предпочитаю компанию один –

ответ

0

Вы можете сделать это с помощью outer apply:

select i.*, t1.id 
from inputs i outer apply 
    (select top 1 t1.* 
     from t1 
     where (t1.Company = '*' or t1.Compay = i.Company) or 
      (t1.Type = '*' or t1.Type = i.Type) 
     order by ((case when t1.company = '*' then 0 else 1 end) + 
       (case when t1.type = '*' then 0 else 1 end) 
       ) desc 
    ) t1; 
0
SELECT TOP 1 * 
FROM [test] 
ORDER BY 
     (CASE WHEN Company = @Company and Type = @Type THEN 1000 ELSE 0 END 
     + CASE WHEN Company = @Company and Type ='*' THEN 900 ELSE 1 END 
     + CASE WHEN Company = '*' and Type = @Type THEN 800 ELSE 2 END 
     + CASE WHEN Company = '*' and Type = '*' THEN 700 ELSE 3 END 
     ) DESC 
0

Вы можете попробовать сильфона решение:

DECLARE @Company2Type TABLE (
    ID  INT NOT NULL 
     UNIQUE NONCLUSTERED, 
    Company VARCHAR(50) NOT NULL, 
    [Type] VARCHAR(50) NOT NULL, 
     PRIMARY KEY CLUSTERED (Company, [Type])  
) 
INSERT @Company2Type 
VALUES 
(1, '*', '*'), 
(2, 'CMP1', '*'), 
(3, 'CMP1', 'TYP1'), 
(4, '*', 'TYP1'), 
(5, '*', 'TYP2'), 
(6, 'CMP1', 'TYP2'); 

DECLARE @TestData TABLE (
    Company VARCHAR(50) NOT NULL, 
    [Type] VARCHAR(50) NOT NULL 
) 
INSERT @TestData 
VALUES 
('CMP1' , 'TYP1'), 
('CMP2' , 'TYP2'), 
('CMP5' , 'TYP5'); 

SELECT *, COALESCE(rule1.ID, rule2.ID, rule3.ID, rule4.ID) AS [Output] 
FROM @TestData td 
OUTER APPLY (
    SELECT ct.ID 
    FROM @Company2Type ct 
    WHERE ct.Company = td.Company 
    AND  ct.[Type] = td.[Type] 
) rule1 
OUTER APPLY (
    SELECT ct.ID 
    FROM @Company2Type ct 
    WHERE rule1.ID IS NULL 
    AND  ct.Company = td.Company 
    AND  ct.[Type] = '*' 
) rule2 
OUTER APPLY (
    SELECT ct.ID 
    FROM @Company2Type ct 
    WHERE rule1.ID IS NULL 
    AND  ct.Company = '*' 
    AND  ct.[Type] = td.[Type] 
) rule3 
OUTER APPLY (
    SELECT ct.ID 
    FROM @Company2Type ct 
    WHERE rule1.ID IS NULL 
    AND  ct.Company = '*' 
    AND  ct.[Type] = '*' 
) rule4 

Результаты:

Company Type ID ID ID ID Output 
------- ---- ---- ---- ---- ---- ------ 
CMP1 TYP1 3 NULL NULL NULL 3 
CMP2 TYP2 NULL NULL 5 1 5 
CMP5 TYP5 NULL NULL NULL 1 1 

Примечания:

  • [Rule1] Обе компании и типы соответствия
  • [Rule2] Компании соответствует и тип испытаний соответствует *
  • [Rule3] Тест компании соответствует * и типы соответствия
  • [Rule4] Обе компании и типы соответствия *
Смежные вопросы