Author |
Topic |
MarcH
Starting Member
2 Posts |
Posted - 2007-07-11 : 12:01:36
|
Hi,I'm trying to work out the median date for a "datetime" field.Below is the SQL I'm using, but this is returning "The row in the middle" as opposed to the calculated median value.Any ideas?select cast(avg(cast(datetime_field as numeric)) as datetime) from ( select datetime_field, count(*)over( ) total, cast(count(*)over( ) as numeric)/2 mid, ceiling(cast(count(*)over( ) as numeric)/2) next, row_number()over( order by datetime_field) rn from tablewhere datetime_field is not null ) xwhere( total%2 = 0 and rn in ( mid, mid+1 ) ) or ( total%2 = 1 and rn = next ) |
|
Michael Valentine Jones
Yak DBA Kernel (pronounced Colonel)
7020 Posts |
Posted - 2007-07-11 : 12:13:52
|
It would be better if you started with an explanation of exactly what you are are trying to do. Some sample data and expected results would be helpful also:Want your questions answered fast? Follow the direction in this linkhttp://weblogs.sqlteam.com/brettk/archive/2005/05/25/5276.aspxAlso, the code you posted appears to be SQL 2005, but you posted on the Transact-SQL (2000) forum. Which are you using?CODO ERGO SUM |
 |
|
MarcH
Starting Member
2 Posts |
Posted - 2007-07-11 : 12:48:50
|
Thanks for the prompt reply!Fortuntly in gathering the data needed to show the problem, the answer presented itself and has now been corrected (ordered by the wrong field ).FWIW: To calculate the Median date for a set of values in SQL 2005, use the SQL below :select cast(avg(cast(<FIELD_NAME> as float)) as datetime) from ( select <FIELD_NAME>, count(*)over( ) total, cast(count(*)over( ) as float)/2 mid, ceiling(cast(count(*)over( ) as float)/2) next, row_number()over( order by <FIELD_NAME>) rn from <TABLE_NAME>where <FIELD_NAME> is not null ) xwhere( total%2 = 0 and rn in ( mid, mid+1 ) ) or ( total%2 = 1 and rn = next ) Marc.quote: Originally posted by Michael Valentine Jones It would be better if you started with an explanation of exactly what you are are trying to do. Some sample data and expected results would be helpful also:Want your questions answered fast? Follow the direction in this linkhttp://weblogs.sqlteam.com/brettk/archive/2005/05/25/5276.aspxAlso, the code you posted appears to be SQL 2005, but you posted on the Transact-SQL (2000) forum. Which are you using?CODO ERGO SUM
|
 |
|
mattyblah
Starting Member
49 Posts |
Posted - 2007-07-13 : 09:46:47
|
Does this help? It's calculating the median of an int field, but can be easily used for datetime fields.declare @t table(val int);insert into @t values (1);insert into @t values (1);insert into @t values (1);insert into @t values (2);insert into @t values (3);insert into @t values (4);insert into @t values (5);insert into @t values (6);insert into @t values (7);select avg(1. * val) as median from(select row_number() over (order by val asc) as sort_asc , row_number() over (order by val desc) as sort_desc , val from @t) t where abs(sort_asc - sort_desc) <= 1 This is also in 2005, which it appears you are using with the row_number() function in the first post. |
 |
|
Jeff Moden
Aged Yak Warrior
652 Posts |
Posted - 2007-07-15 : 13:54:38
|
Ummm... Median IS the "row in the middle"... are you looking for "Average" instead?--Jeff Moden |
 |
|
jsmith8858
Dr. Cross Join
7423 Posts |
Posted - 2007-07-15 : 14:07:13
|
quote: Originally posted by Jeff Moden Ummm... Median IS the "row in the middle"... are you looking for "Average" instead?--Jeff Moden
There are different types of medians, but typically it is the row in the middle for an odd number of rows, or the average of the two middlest rows for an even number of rows. Since the average of one value is that value, avg() works for both situations as long as you get the row(s) you need to use.- Jeffhttp://weblogs.sqlteam.com/JeffS |
 |
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2007-07-15 : 16:18:21
|
Think about itasc desc diff 1 4 3 -- even number of datapoints2 3 13 2 -14 1 -31 3 2 -- odd number of datapoints2 2 03 1 -2select avg(val) as median from(select row_number() over (order by val asc) as sort_asc , row_number() over (order by val desc) as sort_desc , val from table1) as t where sort_asc - sort_desc between -1 and 1 Peter LarssonHelsingborg, Sweden |
 |
|
Jeff Moden
Aged Yak Warrior
652 Posts |
Posted - 2007-07-15 : 18:26:30
|
I was referring to the OP who stated "but this is returning "The row in the middle" as opposed to the calculated median value"...--Jeff Moden |
 |
|
|