日期:2014-05-18  浏览次数:20478 次

有挑战性的难题--抽样统计
declare @t table([id] int NOT NULL,pname varchar(10) NULL,num int NULL) 
insert into @t select 1, 'a ',11 
union all select 2, 'a ',23 
union all select 3, 'b ',34 
union all select 4, 'b ',45 
union all select 5, 'c ',56 
union all select 6, 'b ',78 
union all select 7, 'd ',99 
union all select 8, 'd ',100 


如上表,问题描述: 
一个抽样数据统计的问题,假设该表为销售情况表,字段分别为流水号,员工姓名,销售量,暂不考虑日期问题 
目标:根据输入的抽样数量,如200,需要计算出这200总量里,各员工销售量所占的比例 

抽样统计的问题: 
--假设抽样出的记录id为2,3,4,8,按照销售量和值为sum=202
--希望得到的结果
--
pname num percent
a 23 11.39%
b 79 39.11%
c 0 0%
d 100 49.5%
--
思考: 
1、随机性,满足条件的记录有很多,则需要从这些记录里随机取出记录,如果顺序读取记录并累加的话,则每次取出的抽样结果肯定是一样的,这样就不够客观了 
2、抽样总数为200,但是取出的记录的和值肯定不一定刚好是200,因此以取出的数据为超过200的最小和值为准,如和值累加为190,203,210,取203 
3、记录补全的问题,查询出的记录里,有可能某些员工并没有销售记录,因此需要补全记录,这个倒好办 

摆渡:查了下,MSSQL2000里带有统计功能,CREATE STATISTICS这种,但分析下觉得不能满足我这需求 

谢谢大家帮忙啦!

------解决方案--------------------
抽出的个数能确定吗,如果能,我给你个例自己看看.

表movie中
id mnet
1 10
2 20
3 20
4 30
5 40
6 10
7 10
8 20
9 20
10 20
取5条出来,让其mnet总和等于100
如:id=2,id=4,id=6,id=8,id=9就是一组符合条件的
请教ING...
谢谢了~~

select
a.id,b.id,c.id,d.id,e.id
from
movie a,
movie b,
movie c,
movie d,
movie e
where
a.id<b.id and b.id<c.id and c.id<d.id and d.id<e.id
and
a.mnet+b.mnet+c.mnet+d.mnet+e.mnet=100

------解决方案--------------------
SQL code

use test
go
declare @t table([id] int NOT NULL,pname varchar(10) NULL,num int NULL)  
insert into @t select 1,  'a  ',11  
union all select 2,  'a  ',23  
union all select 3,  'b  ',34  
union all select 4,  'b  ',45  
union all select 5,  'c  ',56  
union all select 6,  'b  ',78  
union all select 7,  'd  ',99  
union all select 8,  'd  ',100  

declare @tmp table([id] int NOT NULL,pname varchar(10) NULL,num int NULL)  

while 200>(select isnull(sum(num),0) from @tmp)
insert @tmp
select 
    top 1 * 
from 
    @t 
where 
    id not in(select id from @tmp )order by NewID()

select pname,[比率]=rtrim(cast(sum(num)*1.0/(select sum(num) from @tmp)*100 as decimal(18,2)))+'%'
 from @tmp  group by pname

select * from @tmp
-----------

pname      比率                                        
---------- ----------------------------------------- 
a          9.39%
b          50.20%
d          40.41%

(所影响的行数为 3 行)

id          pname      num         
----------- ---------- ----------- 
6           b          78
4           b          45
2           a          23
7           d          99

(所影响的行数为 4 行)

------解决方案--------------------
SQL SERVER2005里有一个新的关键词叫做TABLESAMPLE, 就是用来做抽样统计的, 不过好象只能取百分比,譬如1%, 不能取某个数。

不过我想你可以先确定整个表有多少个数据, 然后大概估计出多少个百分比是200条。然后多取一个百分比, 再取前200条就可以了。

至少LZ说的销售记录不全的问题,LZ应该能很轻松解决吧?
SQL code

select top 200 * from 
(   select pname, num, num/sum(num) as [percent]
    from #table
    Tablesample(2)
)T