Rails 3 query specific data from multiple models - ruby-on-rails-3

Here are my two models:
class Account < ActiveRecord::Base
has_many :values
end
class Value < ActiveRecord::Base
belongs_to :account
end
On my account model I have a :name attribute and a :type attribute where I choose either 'checking' or 'savings'. Every quarter of the year I record an amount for each account, this goes on the value model. The value model has a :quarter attribute (either 1, 2, 3, or 4), a :year attribute, and an :amount attribute. Some accounts get updated for every quarter of the year, and some don't. So for example I could have a checking account that has values for the 1,2,3,and 4th quarters of 2010, and then another checking account with values for only the 1st and 2nd quarters. Every time a quarter is entered, it is just an update of the previous quarter, not a running cumulative total.
What I want to do is to run a query that will show me my average account value for last year for a certain account type, 'checking' or 'savings'. The thing I'm struggling with is that I can't just run a query and total the whole year, because only the last entered value (ordered by :quarter and :year) is the actual value, not a total of all the quarters. So how do I loop through all of the 'checking' accounts for example and pull the :amount from most recently entered value entry, whether that was the 1st quarter or the 4th?

I would use the created_at timestamp of the value record to order the results. It sounds like you want the most recent value record within a given range. If you can't order the results by date can you simply order by :quarter DESC and use the first result?
Don't forget about utilizing AVG() functions on the SQL server side: http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_avg
Also check out http://ar.rubyonrails.org/classes/ActiveRecord/Calculations/ClassMethods.html

Related

Adjusting Overlapping Dates and Applying Other Rules

I'm trying to design a SELECT query that will modify some dates in a subset of "activity" records for each person in a table of data.
Each person is identified uniquely using "PersonID" and then each activity record using "RecordID".
Each subset of activity records a person has will also have dates against the "Start Date" and "End Date" fields.
For example, data like this (sorted by start date then longest duration):
(I've added the yellow bars to give an idea of some of the overlap and gaps between sets of dates).
Where I work, we have a task that involves adding a maximum of 1 "claim" record to associate with each of these activity records. The claim records have their own Start Date and End Date, but each claim record must:
Not cover a duration outside of the Start Date and End Date of the activity record it's being attached to.
Not overlap with the duration of any other claim record in the person's subset of claim records
Have a duration of at least 1 month, defined as either: starting on the first day of the month and ending on the last day of the month (e.g. 1/12/2018 to 31/12/2018), or starting in a month but ending in a different month (e.g. 31/12/2018 to 1/1/2019).
This is because the claim records are validated against the activity records (by an external validation tool we have no control over).
So, based on the example above, the query might output the following efficient set of dates for each activity record to use as claim records:
A brief run-down of what would happen on each record:
Record 1: For claim record 1, it used the original dates from the activity records, i.e. create a claim record that covers the entire
activity period. If working through the records in the sort order
described, it would make sense that it simply claims the full activity
period for the first claim record for each person's subset of activity
records.
Record 2: For claim record 2, NULLs have be supplied as there is no period to claim on this activity that hasn't already been claimed
in record 1.
Record 3: For claim record 3, the start date has been set to 1/12/2018, because that is the earliest date to claim from that is
both within this activity period and after the end month of the last
claim (i.e. record 1's 25/11/2019 end date).
The end date has been set to 31/12/2018. You may wonder why it is not
set to the activity's original end date of 23/1/2019. If you look
ahead to record 5, setting record 3's end date to 23/1/2019 would mean
setting record 5's start date to 1/2/2019, and it's end date would be
4/2/2019, which is not long enough to make a claim. So it would be
more efficient to stop record 3 in December so record 5 can claim both
January AND February. This may be hard to script though!
Record 4: For claim record 4, NULLs have be supplied as there is no period to claim on this activity that hasn't already been claimed
in previous claim records.
Record 5: For claim record 5, the start date has been set to 1/1/2019. See record 3 for an explanation of why.
Record 6: For claim record 6, it used the original dates from the activity records. This was just to illustrate that not all activity
records will overlap.
I'm not too sure how to approach this. I've looked at some CTE examples, but nothing that seems to match what I'm trying to do (perhaps too ambitious.. particularly the record 3 & 5 scenario?)
Any help / examples would be much appreciated.

Trouble with an Access Query searching within a date range

I have a query that searches saved records and creates a report based on the record(s). Some of the fields are searchable either independently or in association with other parts of the saved record (e.g., one could search the ID, location, and/or whether or not police were notified). However, I run into problems when searching by date.
I have fields for the user to input Start Date and End Date of their desired date range. When ONE or NEITHER field are filled, the search pulls up all records AFTER the Start Date, BEFORE the end date, or ALL the records. When BOTH fields are filled, the search pulls up a record where all fields are blank (which does not exist in the table).
Each searchable field uses the same criteria in the Query:
Like Nz([field that you're searching],"*")
But the date range uses a modified version (sorry if it's SUPER clunky):
Like Nz(([Data_Input_Table].[Day_Current])>=[Forms]![Search_Form]![Start_Date_Lookup_text] And ([Data_Input_Table].[Day_Current])<=[Forms]![Search_Form]![End_Date_Lookup_text],"*")
Ideally, I'd like the user to search by NEITHER, ONE, or BOTH Start Date and End Date.
Please help!
You can't use Like on dates. Try this:
[Data_Input_Table].[Day_Current] >= Nz([Forms]![Search_Form]![Start_Date_Lookup_text], [Data_Input_Table].[Day_Current]) And [Data_Input_Table].[Day_Current] <= Nz([Forms]![Search_Form]![End_Date_Lookup_text], [Data_Input_Table].[Day_Current])

SSAS - Movement between from and two dates

we have a very specific problem on calculating movement using two dates from and to in cube and details are as follows:
Product group, sub group and asset and liability are derived using client type, product type and closing balance being in credit or debit on a particular day.
Product group, sub group and asset/liability can be selected from a dimension which has a surrogate key that is stored in the fact table against the date key and account key.
Fact table is "account's daily snapshot" which has every day's data starting from the date account was opened till today and the granularity is DateKey and AccountKey.
Consider the scenario that on 15th Jan a particular account was categorised as "Asset" based on associated product type, client type and closing balance value but on the 31st because of the movements after 15th till 31st; it went into "Liability". Now consider that the user would like to see the movements between these two dates and selects "from" and "to" dates in the cube using two date hierarchies.
The "to" date hierarchy runs on a date hierarchy where as "from" date hierarchy is dependent on floating date dimension that does not have any relationship and used with linked member function to get the starting point to perform the sum on "to" date hierarchy.
Now when issuing the two dates 15th and 31st on the cube; behind the scene data from 15th till 31st comes in scope of the selection which has key for asset and liability attribute values.
So when the user choose to show dimension attributes Product group, sub group and asset/liability the cube shows values against attribute values "Asset" and "Liability" which is correct on two rows.
Users would like to see that the asset or liability should be from the "to" date only but should also be able to pass from date to get the sum of movement.
We are wondering if we can keep the closing balance from "to" date and show Product group, sub group and asset/liability dimension attributes using this closing balance and using "from" date just to calculate the sum of movements but not to have impact on Product group, sub group and asset/liability attribute values and subtract it from closing balance to get the desired result.
Any help will be greatly appreciated.

Creating a calculated column (not aggregate) that changes value based on context SSAS tabular DAX

Data: I have a single row that represents an annual subscription to a product, it has an overall startDate and endDate, there is also third date which is startdate + 1 month called endDateNew. I also have a non-related date table (called table X).
Output I'm looking for: I need a new column called Categorisation that will return 'New' if the date selected in table X is between startDate and endDateNew and 'Existing' if the date is between startDate and endDate.
Problem: The column seems to evaluate immediately without taking in to account the date context from the non-related date table - I kinda expected this to happen in visual studio (where it assumes the context is all records?) but when previewing in Excel it carries through this same value through.
The bit that is working:I have an aggregate (an active subscriber count) that correctly counts the subscription as active over the months selected in Table X.
The SQL equivalent on an individual date:
case
when '2015-10-01' between startDate and endDateNew then 'New'
when '2015-10-01' < endDate then 'Existing'
end as Category
where the value would be calculated for each date in table X
Thanks!
Ross
Calculated columns are only evaluated at model refresh/process time. This is by design. There is no way to make a calculated column change based on run-time changes in filter context from a pivot table.
Ross,
Calculated columns work differently than Excel. Optimally the value is known when the record is first added to the model.
Your example is kinda similar to a slowly changing dimension .
There are several possible solutions. Here are two and a half:
Full process on the last 32 days of data every time you process the subscriptions table (which may be unacceptably inefficient).
OR
Create a new table 'Subscription scd' with the primary key from the subscriptions table and your single calculated column of 'Subscription Age in Days'. Like an outrigger. This table could be reprocessed more efficiently than reprocessing the subscriptions table, so process the subscriptions table as incrementals only and do a full process on this table for the data within the last 32 days instead.
OR
Decide which measures are interesting within the 'new/existing' context and write explicit measures for them using a dynamic filter on the date column in the measures
eg. Define
'Sum of Sales - New Subscriptions',
'Sum of Sales - Existing Subscriptions',
'Distinct Count of New Subscriptions - Last 28 Days', etc

Get all entries for this month only

I want to get a count of all my Offer entries for this month. At the moment I use this to make the count:
#offer_count = Offers.find_all_by_accepted(false).count
This works fine, but as you can see it does count all my entries. So my question is how can I change this to only get the count of the entries of this month.
Also I would like to have the possibility to duplicate this and find all my Offers of an specific month. Like get all offers with accepted false and created in January.
Use beginning_of_month to compare the date against:
Order.where('created_at >= ?', Time.now.beginning_of_month)
You could of course substitute created_at for updated_at if that's what you want. You can also add on more where conditions if you need (e.g. .where(:accepted => false), as you seem to need in your question).