Subtract last year's ending quarter value from current quarter value - sql

I know
(DateAdd("s",-1,
DateAdd("q",DateDiff("q","1/1/1900",
DateAdd("yyyy",-1,Date())),"1/1/1900")),
"Short Date")
returns the last day of a quarter 1 year ago.
All of the NAV_Dates are the last day of each quarter, and have a value associated with them which makes the row unique. (Closing value titled as NetAssetValue)
How can I use that (or something similar), to get the value associated with the ending year quarterly date, and subtract it from the value of the current quarter's ending value. Note: I do not have to use this, it's just the only SQL I know that will return a value to somewhat close to what I need.
The table's values would be set up similar to this:
+----------+--------------+
|NAV_Date |NetAssetValue |
+----------+--------------+
|12/31/2012| $4,000|
+----------+--------------+
|03/31/2013| $5,000|
+----------+--------------+
The Year to Date would then be (5,000/4,000) - 1 and saved as a percent. Another example would be:
+----------+--------------+
|NAV_Date |NetAssetValue |
+----------+--------------+
|12/31/2012| $4,000|
+----------+--------------+
|06/30/2013| $4,025|
+----------+--------------+
Year to Date calculation: (4,025/4,000) - 1 and saved as a percent.
I know it involves a nested subquery (or possibly more than one) and that we'd essentially have to capture the current quarter's end, use that value, and capture the prior year's quarter end and use that value also. Just not quite sure how to do it.

You were on the right track considering a correlated subquery for this. I think you want the subquery to return the year-end NetAssetValue for each quarterly record.
I hope the WHERE clause in this query makes the logic clear. However it would force the subquery to run the Year() function against every row in the table. Even so, you may be satisfied with the performance if the table is small enough.
SELECT
y1.NAV_Date,
y1.NetAssetValue,
(
SELECT TOP 1 y2.NetAssetValue
FROM YourTable AS y2
WHERE Year(y2.NAV_Date) = Year(y1.NAV_Date)
ORDER BY y2.NAV_Date DESC
) AS YearEndValue
FROM YourTable AS y1;
I think the following WHERE clause should offer better performance than the one above, assuming NAV_Date is indexed. However, you may find it less intuitive. If so, try the first version and then work on this one later if you need it:
WHERE y2.NAV_Date <= DateSerial(Year(y1.NAV_Date), 12, 31)
Beware, in the current year, the query will return NetAssetValue from the most recent quarterly record as YearEndValue, even though the year hasn't ended. I don't know what else you would want in that situation.
Finally, the query should give you NetAssetValue and YearEndValue for each quarter. All you have left is to add your calculation which uses those values.

Related

SQL LAG function

I tried using the LAG function to calculate the value of previous weeks, but there are gaps in the data due to the fact that certain weeks are missing.
This is the table:
The problem is that the LAG functions takes the previous found week in the table. But I would like it to be zero if the previous week is not consecutive previous week.
This is what I would like it to be:
I'm open to any solutions.
Thank you in advance
Your example data is baffling. You have multiple rows per time frame. The first column looks like a string, which doesn't really make sense for the comparison.
So, let me answer based on a simpler data mode. The answer is to use range. If you had an integer column that specified the time frame:
ordering sales
1 10
2 20
3 30
5 50
Then you would phrase this as:
select max(sales) over (order by ordering range between 1 preceding and 1 preceding)
This would return the value from the "previous" row as defined by the first column. The value would be in a separate column, not a separate row.

How to Calculate Sum untill start of month of a given date in DAX

I would like to calculate Sum(QTY) until the start date of the month for a given date.
Basically I can calculate Sum(QTY) until given date in my measure like:
SumQTYTillDate:=CALCULATE(SUM([QTY]);FILTER(ALL(DimDateView[Date]);DimDateView[Date]<=MIN(DimDateView[Date])))
But I also would like to calculate Sum(QTY) for dates before 10/1/2015 - which is the first date of selected Date's month. I have changed above measure and used STARTOFMONTH function to find first day of the month for a given date like;
.......DimDateView[Date]<=STARTOFMONTH(MIN(DimDateView[Date]))))
but not avail, it gives me
"A function ‘MIN’ has been used in a True/False expression that is
used as a table filter expression. This is not allowed."
What am I missing? How can I use STARTOFMONTH function in my measure?
Thanks.
STARTOFMONTH() must take a reference to a column of type Date/Time. MIN() is a scalar value, not a column reference. Additionally, your measure wouldn't work, because STARTOFMONTH() is evaluated in the row context of your FILTER(). The upshot of all this is that you would get a measure which just sums [QTY] across the first of every month in your data.
The built in time intelligence functions tend to be unintuitive at best. I always suggest using your model and an appropriate FILTER() to get to what you want.
In your case, I'm not entirely sure what you're looking for, but I think you want the sum of [QTY] for all time before the start of the month that the date you've selected falls in. In this case it's really easy to do. Add a field to your date dimension, [MonthStartDate], which holds, for every date in the table, the date of the start of the month it falls in. Now you can write a measure as follows:
SumQTY=SUM(FactQTY[QTY])
SumQTYTilStartOfMonth:=
CALCULATE(
[SumQTY]
;FILTER(
ALL(DimDateView)
;DimDateView[Date] < MIN(DimDateView[MonthStartDate])
)
)

DAX formula for calculate Sum between 2 dates

I have a couple of tables in PowerPivot:
A Stock table - WKRelStrength whose fields are:
Ticker, Date, StockvsMarket% (values are percentages), RS+- (values can be 0 or 1)
A Calendar Table - Cal with a Date field.
There is a many to one relationship between the tables.
I am trying to aggregate RS+-against each row for dates between 3 months ago to the date for that row - i.e a 3 month to date sum. I have tried numerous calculations but the best I can return is an circular reference error. Here is my formula:
=calculate(sum([RS+-]),DATESINPERIOD(Cal[Date],LASTDATE(Cal[Date]),-3,Month))
Here is the xlsx file.
I couldn't download the file but what you are after is what Rob Collie calls the 'Greatest Formula in the World' (GFITW). This is untested but try:
= CALCULATE (
SUM ( WKRelStrength[RS+-] ),
FILTER (
ALL ( Cal ),
Cal[Date] <= MAX ( Cal[Date] )
&& Cal[Date]
>= MAX ( Cal[Date] ) - 90
) )
Note, this will give you the previous 90 days which is approx 3 months, getting exactly the prior 3 calendar months may be possible but arguably is less optimal as you are going to be comparing slightly different lengths of time (personal choice I guess).
Also, this will behave 'strangely' if you have a total in that it will use the last date in your selection.
First of all, the formula that you are using is designed to work as a Measure. This may not work well for a Calculated Column. Secondly, it is better to do such aggregations as a Measure level, than at individual records.
Then again, I do not fully understand your situation, but if it is absolutely important for you to do this at a Record level, you may want to use the "Earlier" Function.
If you want to filter a function, based on a value in the correspontinf row, you just have to wrap your Column name with the Earlier Function. Try changing the LastDate to Earlier in your formula.

Get Most Recent Record

The question speaks for itself, for the most part. I have 2 fields in a table, Date and Value.
By the most recent date, I would like to use the dollar value. I would like to get these values by means of VBA code.
Is this possible with a DLookup or DMax, or something similar?
What I have now searches dates quarterly, however quarterly is not the correct solution I've come to figure out, as the quarterly updates are sent out too late to use.
You can use TOP 1 in a query sorted by Date in descending order.
SELECT TOP 1 y.Date, y.Value
FROM YourTable AS y
ORDER BY y.Date DESC;

Query to find a weekly average

I have an SQLite database with the following fields for example:
date (yyyymmdd fomrat)
total (0.00 format)
There is typically 2 months of records in the database. Does anyone know a SQL query to find a weekly average?
I could easily just execute:
SELECT COUNT(1) as total_records, SUM(total) as total FROM stats_adsense
Then just divide total by 7 but unless there is exactly x days that are divisible by 7 in the db I don't think it will be very accurate, especially if there is less than 7 days of records.
To get a daily summary it's obviously just total / total_records.
Can anyone help me out with this?
You could try something like this:
SELECT strftime('%W', thedate) theweek, avg(total) theaverage
FROM table GROUP BY strftime('%W', thedate)
I'm not sure how the syntax would work in SQLite, but one way would be to parse out the date parts of each [date] field, and then specifying which WEEK and DAY boundaries in your WHERE clause and then GROUP by the week. This will give you a true average regardless of whether there are rows or not.
Something like this (using T-SQL):
SELECT DATEPART(w, theDate), Avg(theAmount) as Average
FROM Table
GROUP BY DATEPART(w, theDate)
This will return a row for every week. You could filter it in your WHERE clause to restrict it to a given date range.
Hope this helps.
Your weekly average is
daily * 7
Obviously this doesn't take in to account specific weeks, but you can get that by narrowing the result set in a date range.
You'll have to omit those records in the addition which don't belong to a full week. So, prior to summing up, you'll have to find the min and max of the dates, manipulate them such that they form "whole" weeks, and then run your original query with a WHERE that limits the date values according to the new range. Maybe you can even put all this into one query. I'll leave that up to you. ;-)
Those values which are "truncated" are not used then, obviously. If there's not enough values for a week at all, there's no result at all. But there's no solution to that, apparently.