English 中文(简体)
How to produce a revenue forecast in SQL?
原标题:

I have a table with a list of contract line items in the form of

CREATE TABLE contracts_lines (
  contract_id integer,
  product_id integer,
  contract_line_start datetime,
  contract_line_end datetime,
  amount float
)

What I would like to produce is a VIEW (or populate a table) that allows me to determine how much revenue I can expect each month - we have a simple rule that each line is recognized evenly over the term of the line (i.e. daily revenue = amount / (contract_line_end - contract_line_start) )

The VIEW will be used as the basis for a measure group in an SSAS cube, so its structure should be something like

montly_revenue_forecast (
  year int,
  month int,
  product_id int,
  contract_id int,
  amount float
)

I d like to do 12 months worth of forecast, from the day it s run and it will run through SSIS so I have access to its contstructs (like looping, etc.) I d prefer not to have to write any stored procedures.

Any help is appreciated

最佳回答

What you need to do is first generate a sequence of dates for each contract/product and then use the sequence to group.

The most convenient way to generate a sequence is to use the rather poorly-documented spt_values table, like so:

WITH Contracts_CTE (contract_id, product_id, contract_day, amount) AS
(
    SELECT 
        cl.contract_id,
        cl.product_id,
        DATEADD(DAY, v.number, cl.contract_line_start),
        cl.amount / DATEDIFF(DAY, cl.contract_line_start, cl.contract_line_end)
    FROM contracts_lines cl
    CROSS JOIN master.dbo.spt_values v
    WHERE v.type =  P 
    AND DATEADD(DAY, v.number, cl.contract_line_start) < cl.contract_line_end
)
SELECT
    DATEPART(YEAR, c.contract_day) AS contract_year,
    DATEPART(MONTH, c.contract_day) AS contract_month,
    c.product_id,
    c.contract_id,
    SUM(Amount) AS contract_amount
FROM Contracts_CTE c
GROUP BY
    c.product_id,
    c.contract_id,
    DATEPART(YEAR, c.contract_day),
    DATEPART(MONTH, c.contract_day)

Just a word of caution - the numbers in spt_values only go from 0 to 2047, so if you have contracts that are more than about 5 years long, then you ll need to generate a longer sequence. Easiest way to do that is to CROSS JOIN the spt_values table to itself, i.e.:

SELECT (v1.number * 2048) + v2.number
FROM master.dbo.spt_values v1
CROSS JOIN master.dbo.spt_values v2
WHERE v1.type =  P 
AND v2.type =  P 
AND ((v1.number * 2048) + v2.number) < 100000

Obviously you d have to integrate that into the above query, but if it s really necessary then it shouldn t be too hard.

问题回答

This isn t the full solution but you probably want to calculate the Montly Revenue for each project based on say 30-day month.

Something like this:

select contract_id, product_id, 
       amount / (datediff(day, contract_line_start, contract_line_end)) * 30 as MontlyRevenue
from contracts_lines




相关问题
SQL SubQuery getting particular column

I noticed that there were some threads with similar questions, and I did look through them but did not really get a convincing answer. Here s my question: The subquery below returns a Table with 3 ...

难以执行 REGEXP_SUBSTR

I m 查询Oracle 10g。 我有两张表格(样本数据见下文)。 i m 试图提取一些领域

SQL Query Shortcuts

What are some cool SQL shorthands that you know of? For example, something I learned today is you can specify to group by an index: SELECT col1, col2 FROM table GROUP BY 2 This will group by col2

PHP array callback functions for cleaning output

I have an array of output from a database. I am wondering what the cleanest way to filter the values is example array Array ( [0] => Array ( [title] => title 1 ...

OracleParameter and DBNull.Value

we have a table in an Oracle Database which contains a column with the type Char(3 Byte). Now we use a parameterized sql to select some rows with a DBNull.Value and it doesn t work: OracleCommand ...

Running numbers in SQL

I have a SQL-statement like this: SELECT name FROM users WHERE deleted = 0; How can i create a result set with a running number in the first row? So the result would look like this: 1 Name_1 2 ...

How to get SQL queries for each user where env is production

I’m developing an application dedicated to generate statistical reports, I would like that user after saving their stat report they save sql queries too. To do that I wrote the following module: ...

热门标签