Я делаю систему, которая назначает аналитиков в соответствии с требованиями клиентов. Я написал процедуру, которая ищет идеального аналитика для выполнения требования.
Основные таблицы:
- grc_analyst (Таблица аналитиков, которые решают требования)
- grc_requirement (Таблица требований) Связь «многие к одному» с grc_analyst. В требованиях есть поле due_date, которое представляет крайний срок, к которому требование должно быть выполнено.
Правила поиска аналитика следующие:
- Число требований, связанных с каждым аналитиком, должны быть подсчитаны.
- Если это число одинаково для всех, то есть аналитикам назначено одинаковое количество требований, то выберите аналитика, чей средний срок выполнения ваших требований самый дальний с текущей даты.
- Если число другое, т. е. у аналитиков другое количество назначенных требований, выберите аналитика с наименьшим количеством назначенных требований.
Здесь это код:
DECLARE @totalRequirementsAnalysts int
DECLARE @idAnalyst int = null
SELECT @totalRequirementsAnalysts =count(distinct(a.requirements))
FROM (
SELECT
a.id,count(r.id) requirements
FROM
grc_analyst a
INNER JOIN grc_analyststate ea ON a.id_analyststate = ea.id AND ea.code = 'A'
INNER JOIN grc_analyst_category ac ON a.id = ac.id_analyst
INNER JOIN grc_category c ON c.id = ac.id_category AND c.code = 'SOAP'
LEFT JOIN grc_requirement r ON a.id = r.id_analyst AND r.id_requirementstate in (
SELECT id from grc_requirementstate er where er.code IN ('AS','ER','DL','DC')
)
group by a.id
) a
IF (@totalRequirementsAnalysts = 1)
BEGIN
PRINT 'Analysts have the same amount of requirements assigned'
SET @idAnalyst = (
SELECT a.id from (
SELECT TOP(1)
a.id,avg (DATEDIFF(DAY,getdate(),r.due_date))average_due_date
FROM
grc_analyst a
INNER JOIN grc_analyststate ea ON a.id_analyststate = ea.id AND ea.code = 'A'
INNER JOIN grc_analyst_category ac ON a.id = ac.id_analyst
INNER JOIN grc_category c ON c.id = ac.id_category AND c.code = 'SOAP'
LEFT JOIN grc_requirement r ON a.id = r.id_analyst AND r.id_requirementstate in (
SELECT id from grc_requirementstate er where er.code IN ('AS','ER','DL','DC')
)
group by a.id
order by average_due_date DESC
) a
)
END
ELSE
BEGIN
PRINT 'Analysts have different number of requirements assigned'
SET @idAnalyst = (
SELECT a.id from (
SELECT TOP(1)
a.id,count(r.id) requirements
FROM
grc_analyst a
INNER JOIN grc_analyststate ea ON a.id_analyststate = ea.id AND ea.code = 'A'
INNER JOIN grc_analyst_category ac ON a.id = ac.id_analyst
INNER JOIN grc_category c ON c.id = ac.id_category AND c.code = 'SOAP'
LEFT JOIN grc_requirement r ON a.id = r.id_analyst AND r.id_requirementstate in (
SELECT id from grc_requirementstate er where er.code IN ('AS','ER','DL','DC')
)
group by a.id
order by requirements ASC
) a
)
END
SELECT ga.id from grc_analyst ga where ga.id = @idAnalyst
Как видите, я использую три запроса, но часть "от" одинакова для всех трех (одинаковые таблицы соединения с одинаковыми условиями). Эта процедура соответствует правилу и работает, но я хочу уменьшить количество запросов, так как есть повторяющийся код.
Tha заранее!