SQL查询以计算每月预算

时间:2018-10-26 01:38:47

标签: sql sql-server tsql

CREATE TABLE [dbo].[EmployeeMonthlyBudget]
(
    [Name] [NVARCHAR](50) NULL,
    [Budget_Day] [MONEY] NULL,
    [DateCreated] [DATETIME] NULL,
    [DateDeleted] [DATETIME] NULL
) 

INSERT INTO [dbo].[EmployeeMonthlyBudget] ([Name], [Budget_Day], [DateCreated], [DateDeleted]) 
VALUES (N'SAM', 20.0000, CAST(N'2018-01-01T00:00:00.000' AS DateTime), CAST(N'2018-10-01T00:00:00.000' AS DateTime)),
       (N'ROB', 10.0000, CAST(N'2018-01-01T00:00:00.000' AS DateTime), NULL),
       (N'TAM', 5.0000, CAST(N'2018-01-01T00:00:00.000' AS DateTime), CAST(N'2018-05-01T00:00:00.000' AS DateTime)),
       (N'TAN', 100.0000, CAST(N'2018-01-01T00:00:00.000' AS DateTime), NULL)   

上面是我们必须计算每月预算的表结构。

我们正在显示每个名称的条形图,其每月预算如何。 假设我们将Sam的1月预算设为620,并将2月预算设为580,依此类推,那么我们需要计算每个月的预算,直到DateDeleted有价值为止

我们能够计算每个员工姓名的每月预算,但无法计算 找出如何连续计算它们。

请任何人帮助我 如何为上述方法编写SQL。 请对表格数据进行采样

a busy cat

1 个答案:

答案 0 :(得分:1)

希望这会有所帮助

SELECT A.Name,A.budget_day,B.MonthName,B.totaldays*A.budget_day as MonthlySpent
FROM 
[dbo].[EmployeeMonthlyBudget] A
inner join(
SELECT [Name] , DATENAME(MONTH, DATEADD(MONTH, nos.monthnos, [DateCreated])-1) AS MonthName,DAY(EOMONTH(DATEADD(MONTH, nos.monthnos, [DateCreated])-1)) as totaldays,month(EOMONTH(DATEADD(MONTH, nos.monthnos, [DateCreated])-1)) as monthOrder
from [dbo].[EmployeeMonthlyBudget]
inner join    (SELECT 1 monthnos UNION SELECT 2 UNION SELECT 3
UNION SELECT 4 UNION SELECT 5 UNION SELECT 6
UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
UNION SELECT 10 UNION SELECT 11 UNION SELECT 12) nos on  nos.monthnos <= DATEDIFF(MONTH, [DateCreated],isnull([DateDeleted],GETDATE()))+1
 ) B on
A.NAME=B.Name 
order by A.Name,monthOrder 

尝试一下

       select name,budget_day,monthname,totalspent from
(Select j.* ,row_number () over (partition by j.name,j.monthname order by j.totalspent) as rn

from

(Select B.name,A.budget_day,MonthName,(datediff(day,[DateCreated],DefaultDate)+1)*A.budget_day as TotalSpent,monthOrder
from (SELECT 
  *, [Budget_Day]*DATEDIFF(day,[DateCreated],isnull([DateDeleted],GETDATE())) as TotalSpent,  DATENAME(MONTH, [DateCreated]) AS MonthNameStart, DATENAME(MONTH,isnull([DateDeleted],GETDATE())) AS MonthNameEND
from 
   [dbo].[EmployeeMonthlyBudget]
 where datecreated<=isnull(datedeleted,getdate())) A
LEFT join 


(
SELECT [Name] , DATENAME(MONTH, DATEADD(MONTH, nos.monthnos-1, [DateCreated])) AS MonthName,EOMONTH([DateCreated]) as DefaultDate ,
DAY(EOMONTH(DATEADD(MONTH, nos.monthnos, [DateCreated])-1)) as totaldays,
month(DATEADD(MONTH, nos.monthnos-1, [DateCreated])) as monthOrder
from [dbo].[EmployeeMonthlyBudget]
inner join    (SELECT 1 monthnos UNION SELECT 2 UNION SELECT 3
UNION SELECT 4 UNION SELECT 5 UNION SELECT 6
UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
UNION SELECT 10 UNION SELECT 11 UNION SELECT 12) nos on  nos.monthnos <= DATEDIFF(MONTH, [DateCreated],isnull([DateDeleted],GETDATE()))

)  B
on A.MonthNameStart =B.MonthName and 
A.Name=B.name

UNION

Select B.name,A.budget_day,MonthName,((datediff(day,DefaultDate,isnull([Datedeleted],getdate())))+1)*A.budget_day as TotalSpent,monthOrder from
(SELECT 
  *, [Budget_Day]*DATEDIFF(day,[DateCreated],isnull([DateDeleted],GETDATE())) as TotalSpent,  DATENAME(MONTH, [DateCreated]) AS MonthNameStart, DATENAME(MONTH,isnull([DateDeleted],GETDATE())) AS MonthNameEND
from 
   [dbo].[EmployeeMonthlyBudget]
   where datecreated<=isnull(datedeleted,getdate())) A
   inner join 


(SELECT [Name] , DATENAME(MONTH, DATEADD(MONTH, nos.monthnos, [DateCreated])-1) AS MonthName,DATEADD(month, DATEDIFF(month, 0, isnull([DateDeleted],getdate())), 0) as DefaultDate,
DAY(EOMONTH(DATEADD(MONTH, nos.monthnos, [DateCreated])-1)) as totaldays,
month(EOMONTH(DATEADD(MONTH, nos.monthnos, [DateCreated])-1)) as monthOrder
from [dbo].[EmployeeMonthlyBudget]
inner join    (SELECT 1 monthnos UNION SELECT 2 UNION SELECT 3
UNION SELECT 4 UNION SELECT 5 UNION SELECT 6
UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
UNION SELECT 10 UNION SELECT 11 UNION SELECT 12) nos on  nos.monthnos <= DATEDIFF(MONTH, [DateCreated],isnull([DateDeleted],GETDATE()))+1)  B
on A.MonthNameEND =B.MonthName and A.Name=B.name

UNION


SELECT B.name,A.budget_day,MonthName,totaldays*A.budget_day as TotalSpent ,monthOrder
FROM 
[dbo].[EmployeeMonthlyBudget] A
inner join(
SELECT [Name] , DATENAME(MONTH, DATEADD(MONTH, nos.monthnos-1, [DateCreated])) AS MonthName,EOMONTH([DateCreated]) as DefaultDate ,
DAY(EOMONTH(DATEADD(MONTH, nos.monthnos-1, [DateCreated]))) as totaldays,
month(DATEADD(MONTH, nos.monthnos-1, [DateCreated])) as monthOrder
from [dbo].[EmployeeMonthlyBudget]
inner join    (SELECT 1 monthnos UNION SELECT 2 UNION SELECT 3
UNION SELECT 4 UNION SELECT 5 UNION SELECT 6
UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
UNION SELECT 10 UNION SELECT 11 UNION SELECT 12) nos on  nos.monthnos <= DATEDIFF(MONTH, [DateCreated],isnull([DateDeleted],GETDATE()))
 where datecreated<=isnull(datedeleted,getdate())
) B on
A.NAME=B.Name


 )j)k
where k.rn=1 and k.name is not null
order by k.name,k.monthOrder