Я написал запрос для расчета общей суммы и суммы всех рискованных = 1 с во время окна. Этот запрос занимает около 800 мс только для записей 40 КБ, есть способ улучшить приведенный ниже запрос.
Здесь я пытаюсь добиться того, чтобы вычислить сумму СУММ и СУММ риска для заданного времени окна, так что я может вычислить процент рискованных элементов за заданное время окна
SELECT
e.entity_uuid AS "entityUuid",
SUM(e.count) AS "totalSum",
tvc.tvcsum AS "totalRiskySum",
ROUND(tvc.tvcsum * 1.0 / SUM(e.count) * 100, 2)::FLOAT AS "percentage"
FROM address_entity e
LEFT JOIN (
SELECT
e.entity_uuid,
SUM(e.count) AS "tvcsum"
FROM address_entity e
WHERE e.depth = 1
AND e.monitoring_report_id IN (
SELECT m.id FROM monitoring_report m
WHERE m.report_date BETWEEN '2020-03-01' AND '2020-03-29'
)
AND e.entity_uuid IN ('393996d1-8df4-414f-8534-bd96f49ce16d','b6497c14-4264-4054-abd3-cb8594fb5072','c2fd62b3-47b3-4fd9-a4ff-a9cf847cd134','e9fa9758-e856-4ce1-9a3a-d0d4b0c35977','5dd4b3b6-cebd-4ce6-93fd-6e59ba8420e7','10d31034-2725-4ac5-937e-4b84e90e3be9')
AND e.category IN ( SELECT category_uuid FROM wiki_entity WHERE risky = 1 GROUP BY category_uuid)
GROUP BY e.entity_uuid
) tvc ON tvc.entity_uuid = e.entity_uuid
WHERE e.depth = 1
AND e.monitoring_report_id IN (
SELECT m.id FROM monitoring_report m
WHERE m.report_date BETWEEN '2020-03-01' AND '2020-03-29'
)
AND e.entity_uuid IN ('393996d1-8df4-414f-8534-bd96f49ce16d','b6497c14-4264-4054-abd3-cb8594fb5072','c2fd62b3-47b3-4fd9-a4ff-a9cf847cd134','e9fa9758-e856-4ce1-9a3a-d0d4b0c35977','5dd4b3b6-cebd-4ce6-93fd-6e59ba8420e7','10d31034-2725-4ac5-937e-4b84e90e3be9')
GROUP BY e.entity_uuid, tvc.tvcsum
Что этот запрос SQL делает?:
ВЫБОР И ВЛЕВО ОБЪЕДИНЯЮТ оба запрашивают одну и ту же таблицу с одинаковым набором фильтров ( в предложении WHERE) единственное отличие состоит в том, что LEFT JOIN добавляет дополнительный фильтр, ограничивающий выбор строк с risky = 1
, где в качестве внешнего выбираются все строки.
Таким образом, мы получаем общую сумму в первом выборе, а также получаем risky = 1
в LEFT JOIN теперь мы можем легко вычислить процент риска для данного временного диапазона как AND e.monitoring_report_id IN (
SELECT m.id FROM monitoring_report m
WHERE m.report_date BETWEEN '2020-03-01' AND '2020-03-29'
)
Вывод запроса: