Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
ttribe
Starting Member
6 Posts |
Posted - 2010-08-16 : 16:17:06
|
| I have a table that has a date field, and then fields showing various statistics about events that occurred on that day (all numeric). Think stock charts with an open, high, low, close, as well as additional fields.I want to take data from the past five days and compare it to any other set of consecutive five days in the table. I've got the self join part down, but i'm struggling to construct something that will say compare the first day, and then if it is a match compare the next day, etc.Any ideas/help would be much appreciated.Thanks. |
|
|
ttribe
Starting Member
6 Posts |
Posted - 2010-08-16 : 17:57:14
|
| maybe some sample data will help clarify my question:create table stockprice (DATE DATETIME,CLOSE numeric (8,4));insert into stockprice values ('8/13/2010', 100.3);insert into stockprice values ('8/12/2010', 99.8);insert into stockprice values ('8/11/2010', 101.1);insert into stockprice values ('8/10/2010', 98);insert into stockprice values ('8/9/2010', 98.5);insert into stockprice values ('8/6/2010', 100);insert into stockprice values ('6/8/2004', 100.3);insert into stockprice values ('6/7/2004', 99.8);etc. etc. going back 10+ years.The first question, which i know how to answer is what other dates are there in the data set where the close is the same as is was on 8/13/2010?I get this using the following:select *from stockprice x, stockprice ywhere x.date >= '8/13/2010' and x.close = y.closeAssuming they occur in the database, this query will find several instances where the close was 100.3, the same as it was on 8/13. In this example, it will returnn '6/8/2004'.So my question is, how do i take that one step further and compare the previous dates, i.e., 8/12 to 6/7 to find the next result? |
 |
|
|
slimt_slimt
Aged Yak Warrior
746 Posts |
Posted - 2010-08-17 : 14:26:46
|
| so which date and|or close are you trying to get?can you write also desired output for clarification.thank you |
 |
|
|
ttribe
Starting Member
6 Posts |
Posted - 2010-08-17 : 17:36:27
|
| I realize the example isn't the best, but it's partially due to the inability to show lots of data points in the example. In my table I have thousands of close values going back years. I want to find a simple way to look at the last five days, and compare it to the previous close value to determine if there was ever a point in time where the values were the same. So if my last five days were:8/13/2010' 100.3'8/12/2010' 99.8'8/11/2010', 101.1'8/10/2010', 98'8/9/2010', 98.5I want to find consecutive dates, if any, where the close values were also:100.399.8101.19898.5The point though is to write it such that i can run it on a periodic basis to check for matches. It's simple enough to find a match for any particular day, but what I'm struggling with is how to write it such that if I get a match on the close value of 100.3, to have the query then check to see if the previous day was 99.8, and then if that matches, the day previous to that was 101.1, etc.I'm not sure if it makes it easier to pull the last five days into a view, for example, but it seems like that's the easy part, and it's looping through the multiple sets of conditions that I can't figure out.Thanks again. |
 |
|
|
khtan
In (Som, Ni, Yak)
17689 Posts |
Posted - 2010-08-18 : 04:02:38
|
Is this what you want ?-- sample table & dataDECLARE @sample TABLE( datecol datetime, val int)INSERT INTO @sampleSELECT '2010-07-05', 1 UNION ALLSELECT '2010-07-04', 2 UNION ALLSELECT '2010-07-03', 3 UNION ALLSELECT '2010-07-02', 4 UNION ALLSELECT '2010-07-01', 5 UNION ALLSELECT '2010-06-30', 6 UNION ALLSELECT '2010-06-03', 1 UNION ALLSELECT '2010-06-02', 2 UNION ALLSELECT '2010-06-01', 3 UNION ALLSELECT '2010-02-20', 1 UNION ALLSELECT '2010-02-19', 2 UNION ALLSELECT '2010-02-18', 3 UNION ALLSELECT '2010-02-17', 4 UNION ALLSELECT '2010-02-16', 5 UNION ALLSELECT '2010-02-15', 6 UNION ALLSELECT '2010-01-10', 1 UNION ALLSELECT '2010-01-09', 2 UNION ALLSELECT '2009-07-30', 1 UNION ALLSELECT '2009-07-29', 2 UNION ALLSELECT '2009-07-28', 3 UNION ALLSELECT '2009-07-27', 4 UNION ALLSELECT '2009-07-26', 5-- QueryDECLARE @start_date datetime, @no_of_dates intSELECT @start_date = '20100705', @no_of_dates = 5; WITH sourceAS( SELECT *, row_no = row_number() OVER (ORDER BY datecol DESC) FROM @sample WHERE datecol <= @start_date AND datecol > DATEADD(DAY, -@no_of_dates, @start_date)),matchAS( SELECT datecol, match_no = row_number() OVER (ORDER BY datecol) FROM @sample s CROSS APPLY ( SELECT cnt = COUNT(*) FROM source s INNER JOIN ( SELECT datecol, val, row_no = row_number() OVER (order BY datecol DESC) FROM @sample x WHERE x.datecol <= s.datecol AND x.datecol > DATEADD(DAY, -@no_of_dates, s.datecol) ) m ON s.row_no = m.row_no AND s.val = m.val ) m WHERE s.datecol < DATEADD(DAY, -@no_of_dates, @start_date) AND m.cnt = @no_of_dates)SELECT m.match_no, s.datecol, s.valFROM match m INNER JOIN @sample s ON s.datecol <= m.datecol AND s.datecol > DATEADD(DAY, -@no_of_dates, m.datecol)/*match_no datecol val ---------- ----------- ----------- 1 2009-07-30 11 2009-07-29 21 2009-07-28 31 2009-07-27 41 2009-07-26 52 2010-02-20 12 2010-02-19 22 2010-02-18 32 2010-02-17 42 2010-02-16 5(10 row(s) affected)*/ KH[spoiler]Time is always against us[/spoiler] |
 |
|
|
ttribe
Starting Member
6 Posts |
Posted - 2010-08-18 : 13:34:34
|
Exactly what i needed. Thank you. Now i need to see if i can understand what you did so i can modify it slightly to adjust for what i need. But that's my issue, not yours. |
 |
|
|
|
|
|
|
|