Reputation: 833
I have a table A that looks like this
Date Name Value
----------------------------
2015-01-01 A 12
2015-01-01 B 13
2015-01-01 C 10
2015-01-01 D 9
2015-01-01 E 15
2015-01-01 F 11
2015-01-02 A 1
2015-01-02 B 2
2015-01-02 C 3
2015-01-02 D 4
2015-01-02 E 5
2015-01-02 F 6
2015-01-03 A 7
2015-01-03 B 8
2015-01-03 C 9
2015-01-03 D 10
2015-01-03 E 15
2015-01-03 F 16
....
Which contains a value for each name for each day. I need a second table which looks like this
Date Name ValueDate ValueDate+1 ValueDate+2
--------------------------------------------------------------
2015-01-01 A 12 1 7
2015-01-01 B 13 2 8
2015-01-01 C 10 3 9
2015-01-01 D 9 4 10
2015-01-01 E 15 5 15
2015-01-01 F 11 6 16
2015-01-02 A 1 7 ...
2015-01-02 B 2 8 ...
2015-01-02 C 3 9 ...
2015-01-02 D 4 10 ...
2015-01-02 E 5 15 ...
2015-01-02 F 6 16 ...
I tried creating an intermediate table which has all the dates correctly entered
Date Name ValueDate ValueDate+1 ValueDate+2
----------------------------------------------------------------
2015-01-01 A 2015-01-01 2015-01-02 2015-01-03
2015-01-01 B 2015-01-01 2015-01-02 2015-01-03
2015-01-01 C 2015-01-01 2015-01-02 2015-01-03
2015-01-01 D 2015-01-01 2015-01-02 2015-01-03
2015-01-01 E 2015-01-01 2015-01-02 2015-01-03
2015-01-01 F 2015-01-01 2015-01-02 2015-01-03
...
My idea then was to use some kind of JOIN on table a to map the the corresponded Values to the dates and use s.th like
CASE WHEN Date = ValueDate THEN Value ELSE NULL END AS ValueDate+1
I am struggling to figure out how this can be done in SQL. I essentially need all the Values over a window for an initial date sequence. To give some background I want to see for a regular time interval how the value behaves in the following x days. The Datatypes are Date for all the Date columns, Varchar for the Name and numerics for the Values. The ValueDate+1 and +2 means +1/2 days. Also it cannot be ruled out that the counts of names stays constant over time.
thanks
Upvotes: 2
Views: 1747
Reputation: 833
I found one way of getting the desired results, by writing a row_number() sub select limit to the desired window size. Which gives each entry per date s.th like this
Date Name Value Row_Num
---------------------------------------
2015-01-01 A 12 0
2015-01-01 A 12 1
2015-01-01 A 12 2
2015-01-01 A 12 3
In the next step one can use
(Date + Row_Num*INTERVAL'1 DAY')::DATE
which then can be joined on the initial table and pivoted. This will allow for any arbitrary combination of Names per date.
Upvotes: 0
Reputation: 1
I'm unclear about your problem statement --
First, you don't say if the "Date" in your data is a Date type, or just a string that looks like a date.
Is "Value" the primary key for each line of data? Or is it an actual value used in the computation of "ValueDate+1"? If so, how?
Is "ValueDate" simply the value of "Date", and "ValueDate+1" the day after the "Date"? Or is it the month after?
Is ValueDate supposed to be the value of the "Date" plus "Value" days?
Could you restate the problem, and include types of your data?
Can you state the problem with equations, or formulas, along with the type of output values you need to show?
If you can, I can show you how to format it in SQL.
-- Ada
Upvotes: 0
Reputation: 1269693
You just want lead()
:
select a.*,
lead(value) over (partition by name order by date) as value_1,
lead(value, 2) over (partition by name order by date) as value_2
from a;
Upvotes: 1