Соответствие и ранжирование запроса с динамическими столбцами и процентным соответствием - PullRequest
1 голос
/ 28 марта 2011

Я пытаюсь написать ранжированную систему поиска / сопоставления для клиента, которая будет проверять запрашиваемые материалы (таблица MaterialRequest) и находить поставщиков (где userprofile.usertype_id = 1), которые могут предоставить материал (ы) и ранжировать результаты, которые могут предоставить большинство или все материалы. Вот схема базы данных, которую я имею:

Таблица профилей пользователей

userprofile_id   int identity  
userprofile_dt   datetime  
first_nm         varchar(50)  
last_nm          varchar(50)  
usertype_id      int (provider = 1, requestor = 2)  

Таблица запросов

request_id       int identity  
request_dt       datetime  
title            varchar(50)  
description      varchar(100)  
userprofile_id   int (where usertype = 2)  

Таблица запроса материалов

material_req_id  int identity  
request_id       int  
material_id      int  

Таблица MaterialProvider

material_pro_id  int identity  
userprofile_id   int (where usertype = 1)  
material_id      int

Таблица материалов

material_id      int identity  
material_desc    varchar(50)  

Так, например, если у меня есть этот запрос:

request_id = 1  
request_dt = 3/28/2011  
title = 'test request'  
desc = null  
userprofile_id = 100 (where usertype_id = 2)  

и эти материалы были запрошены

material_req_id   request_id   material_id
1                 1            10 (steel)
2                 1            11 (copper)
3                 1            12 (titanium)
4                 1            13 (nickel)

и MaterialProvider был заполнен как

material_pro_id   userprofile_id   material_id
1                 2                10 (steel)  
2                 2                11 (copper)  
3                 2                13 (nickel)  
4                 3                11 (copper)  
5                 3                13 (nickel)  
6                 3                12 (titanium)  

Я ожидаю, что мой вывод будет выглядеть как

userprofile_id    steel    copper    nickel    titanium    pct_match  
2                 Y        Y         Y         N           75  
3                 N        Y         Y         Y           75  

где имена столбцов получены из материалов в запросе. Затем сможете найти поставщиков, которые могут предоставить более определенного процента запрашиваемых материалов.

Я начал с временной таблицы и курсора на

  1. добавить столбцы во временную таблицу
  2. , затем переберите 3000+ провайдеров и добавьте тех провайдеров, которые могут предоставить указанные материалы.

Есть ли лучший способ сделать это? Этот процесс занимает слишком много времени и хотел бы получить лучшие / лучшие рекомендации о том, как написать что-то подобное.

Ответы [ 2 ]

1 голос
/ 29 марта 2011
;WITH NormalOutput AS (
  /* normal output: one material per row */
  SELECT
    p.userprofile_id,
    m.material_desc,
    value = CASE WHEN mp.material_pro_id IS NULL THEN 'N' ELSE 'Y' END
  FROM Request r
    INNER JOIN MaterialRequest mr ON r.request_id = mr.request_id
    INNER JOIN Material m ON mr.material_id = m.material_id
    CROSS JOIN (SELECT DISTINCT userprofile_id FROM MaterialProvider) p
    LEFT JOIN MaterialProvider mp
      ON p.userprofile_id = mp.userprofile_id AND mr.material_id = mp.material_id
  WHERE r.request_id = 1
)
SELECT p.*, t.pct_match
FROM (
  /* pivoting the normal output */
  SELECT userprofile_id, steel, copper, titanium, nickel
  FROM NormalOutput n
    PIVOT (MAX(value) FOR material_desc IN (steel, copper, titanium, nickel)) p
) p

INNER JOIN (
  /* aggregating the normal output (calculating percents) */
  SELECT
    userprofile_id,
    pct_match = COUNT(CASE value WHEN 'Y' THEN value END) * 100 / COUNT(*)
  FROM NormalOutput
  GROUP BY userprofile_id
) t

/* joining the two modified outputs */
ON t.userprofile_id = p.userprofile_id
0 голосов
/ 28 марта 2011

Выполните поворот имени материалов в последнюю очередь после того, как вы определили набор целевых поставщиков.Сначала сделайте всю математику, а затем хорошенькое форматирование.

...