먼저 자신에게 캘린더 테이블을 생성하십시오. 그들은 매우 유용합니다!
CREATE TABLE dbo.tCalendar(
Date_Value DATE PRIMARY KEY NOT NULL,
Year AS (DATEPART(YEAR, Date_Value)) PERSISTED,
Month AS (DATEPART(MONTH, Date_Value)) PERSISTED,
Day AS (DATEPART(DAY, Date_Value)) PERSISTED,
Day_Of_Year AS (DATEPART(DY, Date_Value)) PERSISTED,
)
INSERT INTO dbo.tCalendar
SELECT *
FROM (
SELECT DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY (SELECT 1)) - 1, '2000-01-01') AS d
FROM (VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1))v(n)
CROSS JOIN (VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1))w(n)
CROSS JOIN (VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1))x(n)
CROSS JOIN (VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1))y(n)
) cal
WHERE cal.d <= '2027-12-31'
--SELECT * FROM dbo.tCalendar
지금 당신은 단순히 JOIN
달력 테이블이 필요한 결과를 얻을 수 있습니다 더 복잡한 분포를 들어
CREATE TABLE #Project(
Project VARCHAR(100) PRIMARY KEY NOT NULL,
Start_Date DATE,
End_Date DATE,
Days AS (DATEDIFF(DAY, Start_Date,End_Date) + 1) PERSISTED,
Total_Budget DECIMAL(19,2),
Budget_Per_Day AS (CAST(Total_Budget/(DATEDIFF(DAY, Start_Date,End_Date) + 1) AS DECIMAL(19,2))) PERSISTED
)
INSERT INTO #Project (Project, Start_Date, End_Date, Total_Budget)
VALUES
('Project 1', '2017-01-01', '2017-04-10', 100),
('Project 2', '2017-02-05', '2017-04-05', 200),
('Project 3', '2017-02-03', '2017-05-02', 50),
('Project 4', '2017-01-01', '2017-08-03', 300)
SELECT *
FROM #Project
SELECT p.Project
,cal.Date_Value
,p.Budget_Per_Day
FROM #Project p
INNER JOIN dbo.tCalendar cal
ON cal.Date_Value BETWEEN p.Start_Date AND p.End_Date
을 하나 개의 솔루션이 날짜 범위에 의해 저장 예산 할당에 테이블을 가지고있다, 예 :
CREATE TABLE #Project_Budget_Range(
Project VARCHAR(100) NOT NULL,
Range_Start_Date DATE NOT NULL,
Range_End_Date DATE NOT NULL,
Range_Days AS (DATEDIFF(DAY, Range_Start_Date, Range_End_Date) + 1) PERSISTED,
Budget_Allocation_Value DECIMAL(19,0) NULL,
Budget_Allocation_Pct DECIMAL(9,4) NULL,
PRIMARY KEY (Project, Range_Start_Date),
-- End Date >= Start Date
CONSTRAINT CK_Range_Start_End_Date CHECK (Range_End_Date>=Range_Start_Date),
-- Either Budget_Allocation_Value or Budget_Allocation_Pct must have a value (but not both)
CONSTRAINT CK_Allocation_Type CHECK (Budget_Allocation_Value + Budget_Allocation_Pct IS NULL AND COALESCE(Budget_Allocation_Value,Budget_Allocation_Pct) IS NOT NULL)
)
INSERT INTO #Project_Budget_Range
VALUES
('Project 1', '2017-01-01', '2017-01-31', NULL, 0.5),
('Project 1', '2017-02-01', '2017-02-28', 30, NULL),
('Project 1', '2017-03-01', '2017-04-10', 20, NULL)
SELECT * FROM #Project_Budget_Range
SELECT p.Project
,p.Total_Budget
,cal.Date_Value
,CAST(COALESCE(
(b.Budget_Allocation_Pct * p.Total_Budget)/b.Range_Days, -- Allocation by Pct
b.Budget_Allocation_Value/b.Range_Days -- Allocation by value
) AS DECIMAL(19,8)) AS Budget_Allocation
FROM #Project p
INNER JOIN #Project_Budget_Range b
ON p.Project = b.Project
INNER JOIN dbo.tCalendar cal
ON cal.Date_Value BETWEEN b.Range_Start_Date AND Range_End_Date
WHERE p.Project = 'Project 1'
;

당신에게 서지 감사 !!!!!! – FirstRedPepper
모든 프로젝트가 동일한 기준을 사용하는 경우 - 처음 10 %는 예산의 10 %를 사용하고 나머지 50 %는 70 %를 사용하고 남은 40 %는 나머지 20 %의 예산을 사용합니다. 위의 코드? – FirstRedPepper