對於單表,初步想法--拋磚引玉 declare @num as int set @num=(select count(*) from table) if @num %2 =0 exec('select average(colname) from (select top 2 colname from (select top +' (@num+1)/2 +' colname from table order by colname desc)))') else exec('select top 1 colname from (select top +' (@num+1)/2 +' colname from table order by colname desc))')返回結果集中的唯一字段為中位值
设表名tablename ,求中位数的字段是id,且id已排除重复数据。 select avg(id) from (select id from tablename t0 where (select count(*) from tablename t1 where t1.id<t0.id) - (select count(*) from tablename t2 where t2.id>t0.id) in (0,1,-1) )
select median(colname) from tblname
原来以为简单,但现在想想好像没有那么简单。
不只哪位高手能否帮忙?
你用的是MS SQL Server2000否?
如果是多表就更複雜了
關注&學習
不过在sql中编函数的确不容易,我没有这方面的经验,湖泊兄说单表好说,是不是有方法,不妨说说。
函數傳入表名和字段名甚至where條件.如果是多表,那麼無法寫一個通用的函數.
第二种方法,如果参数是语句,那与单表或者多表又有什么关系?
declare @num as int
set @num=(select count(*) from table)
if @num %2 =0
exec('select average(colname) from (select top 2 colname from (select top +' (@num+1)/2 +' colname from table order by colname desc)))')
else
exec('select top 1 colname from (select top +' (@num+1)/2 +' colname from table order by colname desc))')返回結果集中的唯一字段為中位值
这实际上是我说的第二种方法,就是给出了select语句求中位数,既然如此,那么单表和多表就没有影响了。所谓多表应该不是多表中多个字段的中位数,而应该是一个字段的中位数,多表也就只是在from后面出现了。
select avg(id)
from (select id
from tablename t0
where (select count(*)
from tablename t1
where t1.id<t0.id)
-
(select count(*)
from tablename t2
where t2.id>t0.id)
in (0,1,-1)
)
mincount-maxcount=0 (数列有奇数个数时)
mincount-maxcount=1或-1 (数列有偶数个数时)
对所有满足条件的ID,再求平均值就是中位数了。数列有奇数个数时只会有一个这样的ID,平均值就是这个ID了。
数列有偶数个数时会有两个这样的ID,求平均值就对了。关键在于这样的算法需要保证:
1、数列有奇数个数时有且只有一个这样的ID
2、数列有偶数个数时有且只有两个这样的ID
很容易证明以上论断的,不详细说了。