Question

I have a database named Cash_Flow_Statements and I need to create a saved query that calculates a Trailing Twelve Month (TTM) Free Cash Flow.

Here is an example of my database:

Cash_Flow_Statement

And here is the code for my saved query. I have used this code for other calculations so I know it works. I just don't know how to do a Trailing Twelve Month in SQL.

CREATE PROC " & Calculation & " AS _
SELECT Income_Statements.Ticker, Income_Statements.[Year], Income_Statements.Period, _
" & Formula & " AS TTM _
FROM (Income_Statements AS Income_Statements INNER JOIN Balance_Sheets AS Balance_Sheets ON (Income_Statements.Ticker = Balance_Sheets.Ticker) AND (Income_Statements.[Year] = Balance_Sheets.[Year]) AND (Income_Statements.Period = Balance_Sheets.Period)) _
INNER JOIN Cash_Flow_Statements AS Cash_Flow_Statements ON (Balance_Sheets.Ticker = Cash_Flow_Statements.Ticker) AND (Balance_Sheets.[Year] = Cash_Flow_Statements.[Year]) AND (Balance_Sheets.Period = Cash_Flow_Statements.Period)

I need the variable Formula to contain the equation that will calculate the Trailing Twelve Month for Free Cash Flow. Here is what the math looks like:

Free Cash Flow TTM = Sum(Operating Cash Flow MRQ1 + Operating Cash Flow MRQ2 + Operating Cash Flow MRQ3 + Operating Cash Flow MRQ4) - Sum(Capital Expenditures MRQ1 + Capital Expenditures MRQ2 + Capital Expenditures MRQ3 + Capital Expenditures MRQ4)

MRQ = Most Recent Quarter

I need this formula to be in SQL. How do I do this?

UPDATE

Per @Gord Thompson's answer below I have come up with this code:

SELECT Ticker, [Year], Period, (SELECT (SUM(su.Net_Cash_Flow_Operating) - SUM(su.Capital_Expenditures)) _
FROM (SELECT Ticker, [Year], Period, Net_Cash_Flow_Operating, Capital_Expenditures _
FROM Cash_Flow_Statements _
UNION ALL _
SELECT Ticker, [Year] + 1, Period - 4, Net_Cash_Flow_Operating, Capital_Expenditures _
FROM Cash_Flow_Statements) su _
WHERE su.Ticker = s.Ticker AND su.[Year] = s.[Year] AND (su.Period Between s.Period - 3 And s.Period)) _
AS SalesLast12Months _
FROM Cash_Flow_Statements AS s

When this is run by itself it returns exactly what I need. But as I mentioned in my original post I need to be able to set the variable Formula to contain the SQL statement and then insert it into the existing SQL statement.

So I've tried to adapt @Gord Thompson answer and I've come up this this.

Formula:

Formula = “(SELECT (SUM(su.Net_Cash_Flow_Operating) - SUM(su.Capital_Expenditures)) _
FROM (SELECT Ticker, [Year], Period, Net_Cash_Flow_Operating, Capital_Expenditures _
FROM Cash_Flow_Statements UNION ALL SELECT Ticker, [Year] + 1, Period - 4, Net_Cash_Flow_Operating, Capital_Expenditures _
FROM Cash_Flow_Statements) su _
WHERE su.Ticker = Cash_Flow_Statements.Ticker AND su.[Year] = Cash_Flow_Statements.[Year] AND (su.Period Between Cash_Flow_Statements.Period - 3 And Cash_Flow_Statements.Period))”

SQL statement:

"CREATE PROC " & Calculation & " AS SELECT Income_Statements.Ticker, Income_Statements.[Year], Income_Statements.Period, " & Formula & " AS TTM _
FROM (Income_Statements AS Income_Statements _
INNER JOIN Balance_Sheets AS Balance_Sheets ON (Income_Statements.Ticker = Balance_Sheets.Ticker) AND (Income_Statements.[Year] = Balance_Sheets.[Year]) AND (Income_Statements.Period = Balance_Sheets.Period)) _
INNER JOIN Cash_Flow_Statements AS Cash_Flow_Statements ON (Balance_Sheets.Ticker = Cash_Flow_Statements.Ticker) AND (Balance_Sheets.[Year] = Cash_Flow_Statements.[Year]) AND (Balance_Sheets.Period = Cash_Flow_Statements.Period)

This is the result:

enter image description here

Again this is very close but not quite what I need. I believe that I know what causes the code to not work when I adapt it but I don't know how to fix it yet. In @Gord Thompson code the last line is FROM Cash_Flow_Statements AS s. When I insert the variable formula into my existing SQL statement from my original post, the code is FROM (Income_Statements AS Income_Statements _ INNER JOIN Balance_Sheets AS Balance_Sheets ON (Income_Statements.Ticker = Balance_Sheets.Ticker) AND (Income_Statements.[Year] = Balance_Sheets.[Year]) AND (Income_Statements.Period = Balance_Sheets.Period)) _ INNER JOIN Cash_Flow_Statements AS Cash_Flow_Statements ON (Balance_Sheets.Ticker = Cash_Flow_Statements.Ticker) AND (Balance_Sheets.[Year] = Cash_Flow_Statements.[Year]) AND (Balance_Sheets.Period = Cash_Flow_Statements.Period). I'm almost positive that this is where the problems lies but do not know how to correct it.

Was it helpful?

Solution 2

The variable Formula should contain this:

SELECT (SUM(su.Net_Cash_Flow_Operating) - SUM(su.Capital_Expenditures)) FROM (SELECT Ticker, [Year], Period, Net_Cash_Flow_Operating, Capital_Expenditures FROM Cash_Flow_Statements UNION ALL SELECT Ticker, [Year] + 1, Period - 4, Net_Cash_Flow_Operating, Capital_Expenditures FROM Cash_Flow_Statements) su WHERE su.Ticker = c.Ticker AND su.[Year] = c.[Year] AND (su.Period Between c.Period - 3 And c.Period)

OTHER TIPS

Let's not get too hung up on the columns, let's concentrate on selecting the appropriate rows.

Say we had a table named [SalesSummary] containing

Item      FiscalYear  Quarter  TotalSales
--------  ----------  -------  ----------
bicycles        2011        1         100
bicycles        2011        2         200
bicycles        2011        3         300
bicycles        2011        4         400
bicycles        2012        1         500
bicycles        2012        2         600
bicycles        2012        3         700
bicycles        2012        4         800
ham             2011        1          10
ham             2011        2          20
ham             2011        3          30
ham             2011        4          40
ham             2012        1          50
ham             2012        2          60
ham             2012        3          70
ham             2012        4          80

If we wanted to create a query that showed the quarterly figures along with the total sales for the past 12 months (current quarter plus the previous 3 quarters) one might think that we would have to start messing around with IIf() to handle the "wrap around" from one FiscalYear to the next. Fortunately, we don't, because we can just replicate the same data with "fake" quarters for the next FiscalYear: 2011_Q(4) becomes 2012_Q(0), 2011_Q(3) becomes 2012_Q(-1), and so on.

    SELECT
        Item,
        FiscalYear,
        Quarter,
        TotalSales
    FROM SalesSummary
UNION ALL
    SELECT
        Item,
        FiscalYear + 1,
        Quarter - 4,
        TotalSales
    FROM SalesSummary

returns

Item      FiscalYear  Quarter  TotalSales
--------  ----------  -------  ----------
bicycles        2011        1         100
bicycles        2011        2         200
bicycles        2011        3         300
bicycles        2011        4         400
bicycles        2012        1         500
bicycles        2012        2         600
bicycles        2012        3         700
bicycles        2012        4         800
ham             2011        1          10
ham             2011        2          20
ham             2011        3          30
ham             2011        4          40
ham             2012        1          50
ham             2012        2          60
ham             2012        3          70
ham             2012        4          80
bicycles        2012       -3         100
bicycles        2012       -2         200
bicycles        2012       -1         300
bicycles        2012        0         400
bicycles        2013       -3         500
bicycles        2013       -2         600
bicycles        2013       -1         700
bicycles        2013        0         800
ham             2012       -3          10
ham             2012       -2          20
ham             2012       -1          30
ham             2012        0          40
ham             2013       -3          50
ham             2013       -2          60
ham             2013       -1          70
ham             2013        0          80

If we save that query as [SalesUnion] then we can use it to produce our totals like so

SELECT 
    Item,
    FiscalYear,
    Quarter,
    TotalSales,
    (
        SELECT 
            SUM(su.TotalSales) 
            FROM SalesUnion su 
            WHERE su.Item = s.Item 
                AND su.FiscalYear = s.FiscalYear 
                AND (su.Quarter Between s.Quarter - 3 And s.Quarter)
    ) AS SalesLast12Months
FROM SalesSummary s

Or, if you don't want to rely on a saved query you can do it all in one go:

SELECT 
    Item,
    FiscalYear,
    Quarter,
    TotalSales,
    (
        SELECT 
            SUM(su.TotalSales) 
            FROM 
                (
                        SELECT
                            Item,
                            FiscalYear,
                            Quarter,
                            TotalSales
                        FROM SalesSummary
                    UNION ALL
                        SELECT
                            Item,
                            FiscalYear + 1,
                            Quarter - 4,
                            TotalSales
                        FROM SalesSummary
                ) su 
            WHERE su.Item = s.Item 
                AND su.FiscalYear = s.FiscalYear 
                AND (su.Quarter Between s.Quarter - 3 And s.Quarter)
    ) AS SalesLast12Months
FROM SalesSummary s

Either way, the results are

Item      FiscalYear  Quarter  TotalSales  SalesLast12Months
--------  ----------  -------  ----------  -----------------
bicycles        2011        1         100                100
bicycles        2011        2         200                300
bicycles        2011        3         300                600
bicycles        2011        4         400               1000
bicycles        2012        1         500               1400
bicycles        2012        2         600               1800
bicycles        2012        3         700               2200
bicycles        2012        4         800               2600
ham             2011        1          10                 10
ham             2011        2          20                 30
ham             2011        3          30                 60
ham             2011        4          40                100
ham             2012        1          50                140
ham             2012        2          60                180
ham             2012        3          70                220
ham             2012        4          80                260
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top