Author |
Topic |
landau66
Yak Posting Veteran
61 Posts |
Posted - 2014-01-17 : 14:22:33
|
hi everyone!I have a clustered index in a table. this column is of datatype date. how can i retrieve the following?:select [date], valueColumn from myTablewhere [date] = '2000-01-03' and ('2000-01-03'+1) and ('2000-01-03'+2)My Goal ist to retrieve 3 values of valueColumn of 3 subsequent days, calcualte the average of this 3 values and insert this average in a third colum called [average3days].thank you very much in advancelandau |
|
James K
Master Smack Fu Yak Hacker
3873 Posts |
Posted - 2014-01-17 : 15:48:24
|
Like shown below. The thing to keep in mind is that, if you don't have data for next two days, what do you want to do? This will just take what is available and average it. So for the very last day, it will just be the data for that day.Also, if there are gaps in dates, what do you need to do. Do you still want to average only the next 2 calendar days, or do you want to pick the next 3 values. The following picks the next 3 values.SELECT y1.[date], AVG(y2.valueColumn) AS average3daysFROM YourTable y1 CROSS APPLY ( SELECT TOP (3) y2.valueColumn FROM YourTable y2 WHERE y2.date >= y1.date ORDER BY y2.date ) y2 |
|
|
James K
Master Smack Fu Yak Hacker
3873 Posts |
Posted - 2014-01-17 : 15:50:02
|
BTW, if you want to update a column in your table with the computed data, join to that table again - like shown belowUPDATE x1 SET average3days = x2.average3daysFROM YourTable x1 INNER JOIN ( SELECT y1.[date], AVG(y2.valueColumn) AS average3days FROM YourTable y1 CROSS APPLY ( SELECT TOP (3) y2.valueColumn FROM YourTable y2 WHERE y2.date >= y1.date ORDER BY y2.date ) y2 ) x2 ON x1.[date] = x2.[date]; |
|
|
landau66
Yak Posting Veteran
61 Posts |
Posted - 2014-01-17 : 17:02:55
|
Yes, the Dates have gaps. In this Connection I have a question:Is there a way how to address the next or the previous date since the date-field has as well a clustered index? |
|
|
James K
Master Smack Fu Yak Hacker
3873 Posts |
Posted - 2014-01-18 : 12:07:48
|
If you want to get the next date even if there are gaps, use what I had posted earlier. That is,..... CROSS APPLY ( SELECT TOP (3) y2.valueColumn FROM YourTable y2 WHERE y2.date >= y1.date ORDER BY y2.date ) y2.... If you want to get the dates only if they are consecutive, add an additional condition like this: CROSS APPLY ( SELECT TOP (3) y2.valueColumn FROM YourTable y2 WHERE y2.date >= y1.date AND dateadd(dd,2,y1.date) <= y2.date ORDER BY y2.date ) y2 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2014-01-19 : 03:19:46
|
If by any chance you're on SQL 2012, its much easier. just doUPDATE tSET average3days = [3DayAvg]FROM (SELECT average3days,AVG(valueColumn * 1.0) OVER (ORDER BY [date] ROWS BETWEEN CURRENT ROW AND PRECEDING 2) AS [3DayAvg] FROM Table )t ------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/https://www.facebook.com/VmBlogs |
|
|
landau66
Yak Posting Veteran
61 Posts |
Posted - 2014-01-20 : 14:47:42
|
hi!thank you so much. it was exactly what i needed. it took me some days to understand. by the way i am on an SQL-Server 2012many greetingslandau |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2014-01-21 : 05:32:28
|
quote: Originally posted by landau66 hi!thank you so much. it was exactly what i needed. it took me some days to understand. by the way i am on an SQL-Server 2012many greetingslandau
cool see what all you can do with new analytical functions in 2012http://visakhm.blogspot.com/2012/07/extended-analytic-and-window-functions.htmlhttp://visakhm.blogspot.com/2012/07/extended-analytic-and-window-functions_07.html------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/https://www.facebook.com/VmBlogs |
|
|
landau66
Yak Posting Veteran
61 Posts |
Posted - 2014-02-04 : 03:37:19
|
HI!I have to come back to this Topic. I thought I understood it but still I have got some Problems with it. The solution of visakh suggests the following:UPDATE tSET average3days = [3DayAvg]FROM (SELECT average3days,AVG(valueColumn * 1.0) OVER (ORDER BY [date] ROWS BETWEEN CURRENT ROW AND PRECEDING 2) AS [3DayAvg] FROM Table )t Just the select Statement within the parethesis is a Problem. I think it is not in order. At least it does not function for me. The following solution works:select valueColum, AVG(valueColum) over (order by [date] rows between 2 preceding and current row ) as [3DayAvg]from DAX Is it for some reason important to multiplie the valueColumn by 1 like visakh suggested it?The way visakh updates the table (DAX) by this new computed data is not clear to me either. Maybe someone can tell me what kind of update this is or what field within SQL it touches.I really try hard to understand it!Thank you very muchLandau |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2014-02-04 : 06:16:26
|
quote: Originally posted by landau66 HI!I have to come back to this Topic. I thought I understood it but still I have got some Problems with it. The solution of visakh suggests the following:UPDATE tSET average3days = [3DayAvg]FROM (SELECT average3days,AVG(valueColumn * 1.0) OVER (ORDER BY [date] ROWS BETWEEN CURRENT ROW AND PRECEDING 2) AS [3DayAvg] FROM Table )t Just the select Statement within the parethesis is a Problem. I think it is not in order. At least it does not function for me. The following solution works:select valueColum, AVG(valueColum) over (order by [date] rows between 2 preceding and current row ) as [3DayAvg]from DAX Is it for some reason important to multiplie the valueColumn by 1 like visakh suggested it?The way visakh updates the table (DAX) by this new computed data is not clear to me either. Maybe someone can tell me what kind of update this is or what field within SQL it touches.I really try hard to understand it!Thank you very muchLandau
this is new caluse introduced in SQL 2012 as an extension to PARTITION BY.I'm creating a dervied table using select statement and then using it to update the main table field with AVG value. The * 1.0 is to cast it to float datatype to get decimal part in result. you can ignore it if you want only integer partAlso it would help if you can post exact query you tried and also error message you got.------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/https://www.facebook.com/VmBlogs |
|
|
landau66
Yak Posting Veteran
61 Posts |
Posted - 2014-02-04 : 09:56:24
|
Hi!Thank you very much for your immediate reply!update dax2set [MA3] = d.[ma] from(select [close], AVG([close]*1.0) over (order by [date] rows between 2 preceding and current row ) as [ma]from dax2)d This Code updated all the rows of my table. Unfortunatly the value is in all rows the same. It has now in every row the value of the first row of [ma]. Thanks for the Explanation for the multiplication by one and that it is a derived table we are using here.GreetingsLandau |
|
|
landau66
Yak Posting Veteran
61 Posts |
Posted - 2014-02-04 : 10:55:04
|
Hi all!After reading a lot I found a way to do it:update dax2set [MA3] = t.[ma] from(select [date], [close], AVG([close]*1.0) over (order by [date] rows between 2 preceding and current row ) as [ma]from dax2 ) twhere dax2.[date] = t.[date] I hope it is a way which is acceptable for an experienced SQL-Programmer!thank you very much visakh! you gave me valuable hints!!!Landau |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2014-02-10 : 08:59:11
|
quote: Originally posted by landau66 Hi all!After reading a lot I found a way to do it:update dax2set [MA3] = t.[ma] from(select [MA3], AVG([close]*1.0) over (order by [date] rows between 2 preceding and current row ) as [ma]from dax2 ) twhere dax2.[date] = t.[date] I hope it is a way which is acceptable for an experienced SQL-Programmer!thank you very much visakh! you gave me valuable hints!!!Landau
sorry that was actually a typo. you dont need the where condition at alljust this is enoughcheck and see the differenceupdate dax2 tset [MA3] = t.[ma] from(select [date], [close], AVG([close]*1.0) over (order by [date] rows between 2 preceding and current row ) as [ma]from dax2 ) twhere dax2.[date] = t.[date] ------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/https://www.facebook.com/VmBlogs |
|
|
|