Accessing data from multiple rows - sql

So I am having some troubles writing a sql query. It is a financial stock problem and we have two table, one named A and one named B. The dates are divided into periods, so we want to calculate the investment value for the next period based on some criteria of the current period.
For instance, to calculate the investment value of period 2, we first need to compare the price of stock of the first date of period 1 from table A with the strike price of the same date from table B, and then take the max price and divide it by the investment of first date which is given as 10,000. After that, you just simply do 10000/max(price,strike), and then multiply the value by 10000. I know how to get the max which can be done by either using CASE or max, but the difficulty I am facing is that how can I actually get the investment value of the previous period. The example above is an exception because we know the value of the first day. However, if you want to calculate the investment value for period 3, you will first need the value of period 2, and this is where I am stuck at.
EDIT
Table A
Date Price
1/16/15 206
2/20/15 208
3/20/15 205
Table B
Date Strike
1/16/15 195
2/20/15 201
3/20/15 206
For example, the number of shares on 2/20/2015 is 10000(206) = 48.54
And the investment value is 48.54 * 208 = 10096.
206 is the max of 206 and 195, and 208 is the max of 208 and 201.
Thanks in advance!

Related

MDX Show all months for a person if any of the months have a value of "Y" in a separate dimension

Have a funky issue i'm trying to resolve if you'd be so kind.
Measures: BillableHours
Dimensions:
Personnel (EmployeeId, EmployeeName)
Grouping(EmployeePeriodKey, ActiveFlag)
PeriodCalendarYear, CalendarQuarter, CalendarPeriod)
Grouping dimension has flags and calcs that are particular to a person in a period so the PK is the combo of EmployeeId and CalendarPeriod.
Data As Follows:
EmployeeId CalendarPeriod ActiveFlag BillableHours
123 201501 Y 10
123 201502 Y 20
123 201503 N 30
123 201504 Y 40
People are filtering on "Active Flag" = "Y" and missing the "N" row in the results which is not what is desired. Whatever filter I design needs to be flexible enough that at an employee level I need to know if an employee ever had a value of "Y" JUST the periods selected by the query.
Scenario 1: user selects employee 123 for periods 201501:201504 and filters hypothetical flag to "Y" - Billable Hours should be 100, not 70.
Scenario 2: user selects employee 123 for periods 201501:201503 and filters hypothetical flag to "Y" - Billable Hours should be 60, not 30.
Scenario 3: user selects employee 123 for period 201503 and filters hypothetical flag to "Y" - Billable Hours should be 0, not 30. since in this selected group of periods this person was not active for any period
i'm not interested in all siblings, just the ones at a person level. And if person is not selected I need it to know to perform this check on a person level for the periods filtered for. If they have the following
ActiveFlag: "Y"
Fiscal Year: 2016
Group BillableHours
IT Consulting 1000
HR Consulting 1500
It would be understood that those total amounts represent the hours for every employee who was active for any part of FY2016 whether all 12 months or only 1. If someone was active the year before, but weren't in 2016 they should not show up because I only want to interrogate the flags for the periods selected.
Do you want to see Y value when it's non empty? Otherwise N + Y value?
IIF(
[Measures].[BillableHours] > 0,
([Grouping].[ActiveFlag].[All],[Measures].[BillableHours]),
[Measures].[BillableHours]
)
WhatI needed to accomplish with the above is to have all values for a specific employee evaluated to see if any values for that employee were valid. The key to doing that ended up being using EXISTING. Additionally using NON_EMPTY_BEHAVIOR cut down on evaluation cycles because there was no need to evaluate the rows if they weren't active in a time period. I've posted the MDX below.
CREATE HIDDEN UtilizedFTESummator;
[Measures].[UtilizedFTESummator] = Iif([Measures].[Is Active For Utilization Value] > 0,[Measures].[Period FTE],NULL);
NON_EMPTY_BEHAVIOR([Measures].[UtilizedFTESummator]) = [Measures].[Is Active For Utilization Value];
//only include this measure if the underlying employee has values in their underlying data for active in utilization
CREATE MEMBER CURRENTCUBE.[Measures].[FTE Active Utilization]
AS
SUM
(
EXISTING [Historical Personnel].[Employee Id].[Employee Id],
[Measures].[UtilizedFTESummator]
),VISIBLE=0;

Iterate through table by date column for each common value of different column

Below I have the following table structure:
CREATE TABLE StandardTable
(
RecordId varchar(50),
Balance float,
Payment float,
ProcDate date,
RecordIdCreationDate date,
-- multiple other columns used for calculations
)
And here is what a small sample of what my data might look like:
RecordId Balance Payment ProcDate RecordIdCreationDate
1 1000 100 2005-01-01 2005-01-01
2 5000 250 2008-01-01 2008-01-01
3 7500 350 2006-06-01 2006-06-01
1 900 100 2005-02-01 NULL
2 4750 250 2008-02-01 NULL
3 7150 350 2006-07-01 NULL
The table holds data on a transactional basis and has millions of rows in it. The ProcDate field indicates the month that each transaction is being processed. Regardless of when the transaction occurs throughout the month, the ProcDate field is hard coded to the first of the month that the transaction happened in. So if a transaction occurred on 2009-01-17, the ProcDate field would be 2009-01-01. I'm dealing with historical data, and it goes back to as early as 2005-01-01. There are multiple instances of each RecordId in the table. A RecordId will show up in each month until the Balance column reaches 0. Some RecordId's originate in the month the data starts (where ProcDate is 2005-01-01) and others don't originate until a later date. The RecordIdCreationDate field represents the date where the RecordId was originated. So that row has millions of NULL values in the table because every month that each RecordId didn't originate in is equal to NULL.
I need to somehow look at each RecordId, and run a number of different calculations on a month to month basis. What I mean is I have to compare column values for each RecordId where the ProcDate might be something like 2008-01-01, and compare those values to the same column values where the ProcDate would be 2008-02-01. Then after I run my calculations for the RecordId in that month, I have to compare values from 2008-02-01 to values in 2008-03-01 and run my calculations again, etc. I'm thinking that I can do this all within one big WHILE loop, but I'm not entirely sure what that would look like.
The first thing I did was create another table in my database that had the same table design as my StandardTable and I called it ProcTable. In that ProcTable, I inserted all of the data where the RecordIdCreationDate was not equal to NULL. This gave me the first instance of each RecordId in the database. I was able to run my calculations for the first month successfully, but where I'm struggling is how I use the column values in the ProcTable, and compare those to the column values where the ProcDate is the month after that. Even if I could somehow do that, I'm not sure how I would repeat that process to compare the 2nd month's data to the 3rd month's data, and the 3rd month's data to the 4th month's data, etc.
Any suggestions? Thanks in advance.
Seems to me, all you need to do is JOIN the table to itself, on this condition
ON MyTable1.RecordId = MyTable2.RecordId
AND MyTable1.ProcDate = DATEADD(month, -1, MyTable2.ProcDate)
Then you will have all the rows in your table (MyTable1), joined to the same RecordId's row from the next month (MyTable2).
And in each row you can do whatever calculations you want between the two joined tables.

Calculating difference in column value from one row to the next

I am using an Access DB to keep track of Utility Usage on hundreds of accounts. The meters in these accounts have consumption values only per month. I need to take the consumption value of this month and subtract it from the value of the previous month. to get the consumption for this month. I know that in SQL Server, there is a lead/lag function that can calculate those differences. Is there a similar function in access? or is there a simple way to subtract the value in one row from the one above it?
Ex.
The first Line is Billed Date
The Second Line is the Meter Reading
The Third Line is Consumption
1/26/2014
2/25/2014
3/27/2014
4/28/2014
5/26/2014
7/29/2014
0
3163
4567
5672
7065
8468
1538
1625
1404
1105
1393
1403
I do not quite get some of your results, but I think you want something like:
SELECT Meters.MeterDate,
Meters.MeterReading,
(SELECT TOP 1 MeterReading
FROM Meters m WHERE m.MeterDate <Meters.MeterDate
ORDER BY MeterDate DESC) AS LastReading,
[MeterReading]-Nz([LastReading],0) AS MonthResult
FROM Meters
ORDER BY Meters.MeterReading;

SQL Conditional select - calculate running total

I have a stored procedure that calculates requirements for customers based on input that we receive from them.
Displaying this information is not a problem.
What I'd like to do is show the most recent received amount and subtract that from the weekly requirements.
So if last Friday I shipped 150 items and this weeks requirements are 100 items for each day then I'd like the data grid to show 0 for Monday, 50 for Tuesday, 100 for Wednesday - Friday.
I have currently tried using with limited success the sample select statement -
Select Customer, PartNumber, LastReceivedQty, Day1Qty, Day2Qty, Day3Qty, Day4Qty, Day5Qty,
TotalRequired
FROM Requirements
Obviously the above select statement does nothing but display data as it is in the table. So when I add the case state as follows I get a bit closer to what I need but not fully and I'm unsure how to proceed.
Select Customer, PartNumber, LastReceivedQty,
"Day1Qty" = case When Day1Qty > 0 then Day1Qty - LastReceivedQty end
...
This method works ok as long as the LastReceivedQty is less than the Day1 requirements but it's incorrect because it allows a negative number to be displayed in day one rather than pulling the remainder from day2.
Sample Data looks like the following:
Customer PartNumber LastReceivedQty Day1Qty Day2Qty Day3Qty Day4Qty Day5Qty TotalRqd
45Bi 2526 150 -50 100 100 100
In the sample above the requirements for part number 2526 Day 1 are 100 and the last received qty is 150
The day1qty shows -50 as opposed to zeroing out day 1 and subtract from day2, 3, etc.
How do I display those figures without showing a negative balance on the requirement dates?
Any help/suggestions on this is greatly appreciated.

identifying trends and classifying using sql

i have a table xyz, with three columns rcvr_id,mth_id and tpv. rcvr_id is an id given to a customer, mth_id is a column which stores the month number( mth_id is calculated as (2012-1900) * 12 + 1,2,3.. ( depending on the month). So for example Dec 2011 will have month_id of 1344, Jan 2012 1345 etc. Tpv is a variable which shows the customers transaction amount.
Example table
rcvr_id mth_id tpv
1 1344 23
2 1344 27
3 1344 54
1 1345 98
3 1345 102
.
.
.
so on
P.S if a customer does not have a transaction in a given month, his row for that month wont exist.
Now, the question. Based on transactions for the months 1327 to 1350, i need to classify a customer as steady or sporadic.
Here is a description.
The above image is for 1 customer. i have millions of customers.
How do i go about it? I have no clue how to identify trends in sql .. or rather how to do it the best way possible.
ALSO i am working on teradata.
Ok i have found out how to get standard deviation. Now the important question is : How do i set a standard deviation limit on my own? i just cant randomly say "if standard dev is above 40% he is sporadic else steady". I thought of calculating average of standard deviation for all customers and if it is above that then he is sporadic else steady. But i feel there could be a better logic
I would suggest the STDDEV_POP function - a higher value indicates a greater variation in values.
select
rcvr_id, STDDEV_POP(tpv)
from yourtable
group by rcvr_id
STDDEV_POP is the function for Standard Deviation
If this doesn't differentiate enough, you may need to look at regression functions and variance.