将每月成本除以每日记录在SQL Server查询中

时间:2018-05-30 06:01:19

标签: sql-server

我的表中有两种类型的费用,如何显示该特定月份的每月每月费用我的意思是每月费用(5000)需要潜水30天(2018-05-16-2016-06- 15)每日金额5000/30 = 166.66必须在我的每日报告中显示。

感谢您的帮助。 enter image description here

SELECT  [ExpensesID]
  ,[ExpDate]
  ,[ExpsType]
  ,[ExpDetails]
  ,[ExpAmount]
  ,[USDRate]
  ,[ExpenseBy]
  FROM [PSationMIS].[dbo].[Expenses]

ExpensesID  ExpDate ExpsType    ExpDetails  ExpAmount   USDRate ExpenseBy

1   2018-05-16  Daily   Lunch Cost  40.000  71.000  NULL
2   2018-05-16  Monthly Office Rent 5000.000    71.000  NULL

我想看到这样的结果:

ExpensesID  ExpDate ExpsType    ExpDetails  ExpAmount   USDRate ExpenseBy

1   2018-05-16  Daily   Lunch Cost  40.000  71.000  NULL
2   2018-05-16  Monthly Office Rent 166.66.000  71.000  NULL (As daily cost)
3   2018-05-16  Monthly Office Rent 166.66.000  71.000  NULL
4   2018-05-16  Monthly Office Rent 166.66.000  71.000  NULL
5   2018-05-16  Monthly Office Rent 166.66.000  71.000  NULL
......
30  2018-05-16  Monthly Office Rent 166.66.000  71.000  NULL

我在表格上添加了一个计算列来计算当天的数字,然后使用datediff函数我将成本除以当天的数字。

亲爱的EzLo您能否请生成此查询的天数:

    SELECT 

 [ExpensesID]
      ,[ExpDate]
      ,[ExpsType]
      ,[ExpDetails]
      ,[ExpAmount]
      ,[USDRate]
      ,[ExpenseBy], DATEADD(MONTH, 1, ExpDate)
      ,sum(CASE
              WHEN ExpsType = 'monthly' and  ExpDate between ExpDate and DATEADD(MONTH, 1, ExpDate)  THEN ExpAmount/ DATEDIFF(DAY,ExpDate,enddate)   else ExpAmount
           END) AS CostPerDay
  FROM [Expenses]

  group by [ExpensesID]
      ,[ExpDate]
      ,[ExpsType]
      ,[ExpDetails]
      ,[ExpAmount]
      ,[USDRate]
      ,[ExpenseBy]

1 个答案:

答案 0 :(得分:1)

您可以按照此解决方案。我们计算第一个CTE中每个月的总数,然后使用递归CTE,我们每月生成30行,每日金额,最后使用UNION ALL加入拆分月租和其他费用。

;WITH MonthTotals AS
(
    SELECT
        Year = YEAR(T.ExpDate),
        Month = MONTH(T.ExpDate),
        Total = SUM(T.ExpAmount)
    FROM
        [PSationMIS].[dbo].[Expenses] AS T
    GROUP BY
        YEAR(T.ExpDate),
        MONTH(T.ExpDate)
),
RecursiveDailyRent AS -- Generate 30 rows with the same daily amount (per month) 
(
    SELECT
        T.Year,
        T.Month,
        DailyTotal = T.Total / 30,
        LoopCounter = 1
    FROM
        MonthTotals AS T

    UNION ALL

    SELECT
        R.Year,
        R.Month,
        DailyTotal = DailyTotal,
        LoopCounter = R.LoopCounter + 1
    FROM
        RecursiveDailyRent AS R
    WHERE
        R.LoopCounter <= 30
)
SELECT  
    [ExpensesID],
    [ExpDate],
    [ExpsType],
    [ExpDetails],
    [ExpAmount],
    [USDRate],
    [ExpenseBy]
FROM
    [PSationMIS].[dbo].[Expenses] AS E
UNION ALL
SELECT
    [ExpensesID] = NULL,
    [ExpDate] = DATEFROMPARTS(R.Year, R.Month, 1),
    [ExpsType] = 'Monthly Office',
    [ExpDetails] = 'Rent',
    [ExpAmount] = R.DailyTotal,
    [USDRate] = NULL,
    [ExpenseBy] = NULL
FROM 
    RecursiveDailyRent AS R
ORDER BY
    ExpDate

请务必查看联盟所有第二个选项的列,因为我默认写了一些。

编辑:查询以动态生成天数(请务必查看并在最终结果中添加正确的UNION

;WITH DailyRent AS
(
    SELECT 
        [ExpensesID]
        ,[ExpDate]
        ,[ExpsType]
        ,[ExpDetails]
        ,[ExpAmount]
        ,[USDRate]
        ,[ExpenseBy], 
        DATEADD(MONTH, 1, ExpDate) AS ExpDateNextMonth
        ,sum(CASE
              WHEN ExpsType = 'monthly' and  ExpDate between ExpDate and DATEADD(MONTH, 1, ExpDate)  THEN ExpAmount/ DATEDIFF(DAY,ExpDate,enddate)   else ExpAmount
           END) AS CostPerDay
    FROM 
        [Expenses]
    WHERE
        ExpsType = 'monthly'
    group by 
        [ExpensesID]
      ,[ExpDate]
      ,[ExpsType]
      ,[ExpDetails]
      ,[ExpAmount]
      ,[USDRate]
      ,[ExpenseBy]
),
RecursiveDailyRent AS
(
    SELECT
        CostPerDay = T.CostPerDay,
        ExpDate = T.ExpDate,
        ExpDateNextMonth = T.ExpDateNextMonth
    FROM
        DailyRent AS T

    UNION ALL

    SELECT
        CostPerDay = R.CostPerDay,
        ExpDate = DATEADD(DAY, 1, R.ExpDate),
        ExpDateNextMonth = R.ExpDateNextMonth
    FROM
        RecursiveDailyRent AS R
    WHERE
        DATEADD(DAY, 1, R.ExpDate) < R.ExpDateNextMonth
)
SELECT
    *
FROM
    RecursiveDailyRent AS R

请注意,我在第一次CTE时仅过滤了monthly费用,因为我认为这些是唯一需要每天拆分的费用。您最终可以UNION ALL费用non monthly这些结果。