У меня есть две таблицы
Table of projects
ProjectID, SOP, IncomeA, IncomeB
1 2021-01 100.000 0
2 2022-11 5.000 2.000
Table of income per year per project
ProjectID, SOPOffset, Price, Volumn
1 0 10 1.000
1 1 10 2.000
2 0 15 1.000
2 1 20 500
2 2 20 500
Столбец SOPOffset
относится к году столбца SOP
. Таким образом, проект 1 имеет доход в 2021 и 2022 годах, а проект 2 - в 2022, 2023 и 2024 годах.
Результат существующего запроса:
year income
2021 1.000 -- #1 offset 0
2022 3.000 -- #1 offset 1 + #2 offset 0
2023 500 -- #2 offset 1
2024 500 -- #2 offset 2
Новое требование состоит в том, чтобы столбцы IncomeA
и IncomeB
необходимо распространять максимум на 3 года на проект. Это означает, что проект 1 с 2 SOPOffset
s добавит 50.000
к 2021 и 2022 годам, а проект 2 с 3 SOPOffset
s добавит 2333,34 к 2022 году и 2333,33 к 2023 и 2024 годам
year income
2021 51.000 -- #1 offset 0 + (100.000 + 0)/2
2022 55.333,34 -- #1 offset 1 + #2 offset 0 + (100.000 + 0)/2 + 7000/3 (rounded up to 2333,34)
2023 2,833,34 -- #2 offset 1 + 7000/3 (rounded down to 2333,33)
2024 2,833,34 -- #2 offset 2 + 7000/3 (rounded down to 2333,33)
Возможно ли это новое требование в одном запросе? Мое текущее решение реализовано в самом коде приложения или с использованием циклов, et c in SQL.
Edit 03.08.2020 15: 30 Как указано в комментарии, это существующий запрос, который использует немного другую структуру таблицы и некоторую дополнительную информацию для построения полного набора результатов
SELECT
YEAR(cp.datSOP) + pv.intYearOffset,
SUM(pv.decPrice / cr.decRate * pv.intVolume) as IntakeEUR
FROM
tblProjectVolume pv
INNER JOIN tblProject sp ON sp.intProjectId = pv.intProjectId
INNER JOIN tblCustomerProject cp ON cp.intCustomerProjectId = sp.intCustomerProjectId AND (YEAR(cp.datSOP) + pv.intYearOffset >= 2019)
INNER JOIN tblCurrency c ON c.intCurrencyId = sp.intCurrencyId
INNER JOIN tblCurrencyRate cr ON cr.intCurrencyId = c.intCurrencyId AND cr.intYear = 2019
group by
YEAR(cp.datSOP) + pv.intYearOffset
order by
YEAR(cp.datSOP) + pv.intYearOffset
Подробный результат имеет дополнительное соединение и группировку по
SELECT
YEAR(cp.datSOP) + pv.intYearOffset, bu.intBusinessDivisionId,
SUM(pv.decPrice / cr.decRate * pv.intVolume) as IntakeEUR
FROM
tblProjectVolume pv
INNER JOIN tblProject sp ON sp.intProjectId = pv.intProjectId
INNER JOIN tblCustomerProject cp ON cp.intCustomerProjectId = sp.intCustomerProjectId AND (YEAR(cp.datSOP) + pv.intYearOffset >= 2019)
INNER JOIN tblCurrency c ON c.intCurrencyId = sp.intCurrencyId
INNER JOIN tblCurrencyRate cr ON cr.intCurrencyId = c.intCurrencyId AND cr.intYear = 2019
INNER JOIN tblProductMapping pm ON pm.intProductMappingId = sp.intProductMappingId
INNER JOIN tblBusinessUnit bu ON bu.intBusinessUnitId = pm.intBusinessUnitId
group by
YEAR(cp.datSOP) + pv.intYearOffset, bu.intBusinessDivisionId
order by
YEAR(cp.datSOP) + pv.intYearOffset, bu.intBusinessDivisionId