如何从单年记录中每月报告服务确认

时间:2016-01-13 21:10:54

标签: sql view report

我想从发票中查看每月的金额,该发票的金额值适用于serviceFromDate和serviceToDate整年的服务。

假设我在2015-10-16发出发票,它有一个lineItem,其中包含以下信息:

lineItemDescription: product subscription
customerRetailPrice: 4000.00
serviceFromDate:     2015-10-16
serviceToDate:       2016-10-15
invoiceNumber:       NZ-416

所以我想得到的是服务识别,它将全年的每月收入(精确到天数)等同起来。

我期望的是以下列作为列或单个行(不确定哪个更容易)

yearMonth:           2015-10
daysofService:       15       // days diff between 16th and EOM
serviceRevenue:      164.38   // ($4000/365=10.96) * 15
lineItemDescription: product subscription
invoiceNumber:       NZ-416

yearMonth:           2016-10
daysofService:       15       // days left in last month
serviceRevenue:      328.76   // ($4000/365=10.96) * 15
lineItemDescription: product subscription
invoiceNumber:       NZ-416

... each month value for the year based upon days per month

yearMonth:           2015-11
daysofService:       30       // days of full month November
serviceRevenue:      164.38   // ($4000/365=10.96) * 30
lineItemDescription: product subscription
invoiceNumber:       NZ-416

该视图将显示本月生成的所有发票,因此我认为通过invoiceNumber创建一个行组并从当前月份开始每月自动生成列到最大服务所需的月数到年月。部分发票仅适用于当前或三个月的期间,因此其他月份的列将为NULL。

我可以在Excel中执行我想要的操作,报告结果如下所示,谢谢 enter image description here

1 个答案:

答案 0 :(得分:1)

最好的选择(IMO)是确保您的数据库有一个Calendar表。然后,您可以在此表上JOIN获取此类要求,并使这些任务更加简单。例如:

SELECT
    CAST(YEAR(C.calendar_date) AS CHAR(4)) + '-' + RIGHT('0' + CAST(MONTH(C.calendar_date) AS VARCHAR(2)), 2) AS yearMonth,
    COUNT(*) AS daysofService,
    T.customerRetailPrice/(DATEDIFF(DY, serviceFromDate, serviceToDate) * COUNT(*)) AS serviceRevenue,
    T.lineItemDescription,
    T.invoiceNumber
FROM
    My_Table T
INNER JOIN Calendar C ON C.calendar_date BETWEEN T.serviceFromDate AND T.serviceToDate
GROUP BY
    CAST(YEAR(C.calendar_date) AS CHAR(4)) + '-' + RIGHT('0' + CAST(MONTH(C.calendar_date) AS VARCHAR(2)), 2),
    T.customerRetailPrice,
    T.lineItemDescription,
    T.invoiceNumber

我没有测试过这段代码,因此可能需要进行一些调整,但它应该会让你非常接近。

Calendar表只是一个每天都有一个条目的表。为它生成行可以很容易地延续100年(或者如果你需要它可以更多)。然后,您可以为business_quarter,is_holiday等等添加列。

以下是Calendar表的外观示例。您可以添加您可能需要的特定于您自己的业务/应用程序的任何其他列:

CREATE TABLE Calendar (
    calendar_date    DATE    NOT NULL,
    is_holiday       BIT     NOT NULL DEFAULT (0),
    quarter          CHAR(2) NOT NULL CHECK quarter IN ('Q1', 'Q2', 'Q3', 'Q4'),    
    CONSTRAINT PK_Calendar PRIMARY KEY CLUSTERED (calendar_date)
)