-- ============================================================================= -- Процедура пересчёта roic_norm для manufacturers -- Параметры: @manufacturer_id INT = NULL — id строки в manufacturers; если NULL, пересчёт для всех -- Формула: avgReturnDay = logistics_days + days_of_sales/2 -- frozenDays = avgReturnDay - effectiveDeferralDays (из этапов оплаты) -- roic_norm = 12 / (frozenDays/30) * 100 -- ============================================================================= USE [mag_pbi] GO IF OBJECT_ID(N'[analytics].[sp_recalc_roic]', N'P') IS NOT NULL DROP PROCEDURE [analytics].[sp_recalc_roic]; GO CREATE PROCEDURE [analytics].[sp_recalc_roic] @manufacturer_id INT = NULL AS SET NOCOUNT ON; ;WITH stage_agg AS ( SELECT manufacturer_id, SUM([percent] / 100.0 * [days]) AS effective_deferral_days, SUM([percent] / 100.0) AS total_percent FROM [analytics].[manufacturer_payment_stage] WHERE @manufacturer_id IS NULL OR manufacturer_id = @manufacturer_id GROUP BY manufacturer_id ), calc AS ( SELECT man.id, man.days_of_sales, man.logistics_days, COALESCE(s.effective_deferral_days, 0) AS effective_deferral_days, COALESCE(s.total_percent, 0) AS total_percent, (ISNULL(man.logistics_days, 120) + ISNULL(man.days_of_sales, 180) / 2.0) AS avg_return_day FROM [analytics].[manufacturers] man LEFT JOIN stage_agg s ON s.manufacturer_id = man.id WHERE @manufacturer_id IS NULL OR man.id = @manufacturer_id ), roic_calc AS ( SELECT id, CASE WHEN total_percent <= 0 THEN NULL WHEN (avg_return_day - effective_deferral_days) <= 0 THEN NULL ELSE ROUND(12.0 / ((avg_return_day - effective_deferral_days) / 30.0) * 100.0, 2) END AS new_roic FROM calc ) UPDATE man SET man.roic_norm = r.new_roic FROM [analytics].[manufacturers] man JOIN roic_calc r ON r.id = man.id; SELECT @@ROWCOUNT AS updated_count; GO -- Примеры вызова: -- EXEC [analytics].[sp_recalc_roic]; -- пересчёт для всех -- EXEC [analytics].[sp_recalc_roic] @manufacturer_id = 5; -- только для id=5