统计技术

mysql cookbook00013

统计技术

本章讨论的主题
  • 数据描述技术,比如计算描述统计、产生频率分布、计数缺失值、以及最方回归、相关系数
  • 随机方法,不如如何产生随机数并且利用他们随机化一个行集合或者从行中随机的选择独立的条目
  • 等级分配
13.1 计算描述统计
统计值:
  • 数据数目、总和、范围(最大/最小值)
  • 集中趋势的度量,如平均数、中间数、众数
  • 变化的度量,如标准差和方差
除了中间数、众数其他的可以通过聚集函数很容易的计算出来:
SELECT COUNT(score) as n,SUM(score) as sum,MIN(score) as min,MAX(score) as max,
AVG(score) as mean,STDDEV_SAMP(score) as 'std. dev.'//标准差
VAR_SAMP(score) as 'variance' FROM testscore//方差
注意:STDDEV_SAMP()和VAR_SAMP()函数产生的是采样方法而不是总体方法。也即是说,对于一个有n个值的集合,他们根据n-1的自由度产生
结果。如果使用总体方法,如STDDEV_POP和VAR_POP函数,则基于n自由度。其实上面的四个函数是同义的。
标准差可以用来确定外位置,即那么些远离均值的值。举个例子,选择与均值的差值大于3倍标准差的值:
SELECT @mean := AVG(score),@std:= STDDEV_SAMP(score) FROM testscore;
SELECT score FROM testscore WHERE ABS(score - @mean) > @std*3;
在MYSQL中没有众数、中间数的内建函数,但是你可以计算出来:
1.众数:在表中出现频率最高的那条记录值
2.中间数:表中的中间的那条记录
一个有序的集合的中间数:
如果值的数据是基数,中间数就是顺序位于最中间的值
如果是偶数,中间数就是位于中间顺序的两个值的平均值
通过下面的过程来判断数据库中的中间数的确定:
产生技术观测值数目的查询,根据数目可以判定中间数是一个还是两个的平均值
通过一个包含ORDER BY 子句的查询以排序数据。并使用LIMIT子句以取得中间值
如果中间值只有一个,那么就是中间数,否则中间就是中间值的平均值
举例1:37的这个数:SELECT score from testscore ORDER BY score LIMIT(18,1)//取中间数
举例2:38的这个数:SELECT score FROM testscore ORDER BY score LIMIT(18,2)//先减1取1个中间数和下一个数的平均值

13.2 分组描述统计
通过GROUP BY 子句来分组,再通过聚集函数
ISNULL(val)函数当里面的值为NULL那么将返回1否则返回0

13.6 生成随机数
调用MYSQL的RAND(val)函数:产生的值在0-1之间;中间的参数是随机因子
13.7 随机化行集合
使用 ORDER BY RAND()
讨论: MYSQL的RAND()函数可以被用来对查询所返回的行进行随机排序,通过在每个行中增加一个包含随机选择数的列
然后根据随机数排序,排序以后那么与起对应的行记录也相应的被随机排列了:
mysql> select * from tab2 order by rand();
+----+------+----------+
| id | name | addr |
+----+------+----------+
| 6 | ddd | nanjing |
| 4 | abc | sichuan |
| 1 | aaa | jiangxi |
| 3 | ccc | shanghai |
| 2 | bbb | beijing |
| 5 | eee | hunan |
+----+------+----------+
6 rows in set (0.06 sec)

mysql> select * from tab2 order by rand();
+----+------+----------+
| id | name | addr |
+----+------+----------+
| 6 | ddd | nanjing |
| 5 | eee | hunan |
| 1 | aaa | jiangxi |
| 3 | ccc | shanghai |
| 4 | abc | sichuan |
| 2 | bbb | beijing |
+----+------+----------+
6 rows in set (0.00 sec)

13.8 从行集合中随机选择条目
随机排列这些值,然后选择第一个(或者前面几个)
13.9 分配等级
计算分配等级有三种方式:
  1. 是通过在数值的有序集中为每个值赋予他们的行号,为了产生这种行号,需要知道行号并使用它来作为当前的值
mysql> set @rownum = 0;
Query OK, 0 rows affected (0.00 sec)

mysql> select @rownum = @rownum + 1 as 'rank' ,price from painting order by price;
+------+-------+
| rank | price |
+------+-------+
| 0 | 34 |
| 0 | 34 |
| 0 | 48 |
| 0 | 48 |
| 0 | 64 |
| 0 | 67 |
+------+-------+
6 rows in set (0.00 sec)

mysql> select @rownum := @rownum + 1 as 'rank' ,price from painting order by price;
+------+-------+
| rank | price |
+------+-------+
| 1 | 34 |
| 2 | 34 |
| 3 | 48 |
| 4 | 48 |
| 5 | 64 |
| 6 | 67 |
+------+-------+

2. 上面的分级方式并没有考虑平分的可能性,第二种方式是重视这么一点的,只有值发生了变化才增加排名
Query OK, 0 rows affected (0.00 sec)

mysql> select @rank :=IF(price != @pre_val,@rank+1,@rank) as 'rank',@pre_val := price as 'price' from painting order by price ;
+------+-------+
| rank | price |
+------+-------+
| 1 | 34 |
| 1 | 34 |
| 2 | 48 |
| 2 | 48 |
| 3 | 64 |
| 4 | 67 |
+------+-------+
6 rows in set (0.00 sec)

mysql>

3. 第三种方式结合了上面的两种方式来排名的

mysql> set @rownum = 0,@rank = 0,@pre_val= NULL;
Query OK, 0 rows affected (0.00 sec)

mysql> select @rownum:= @rownum + 1 as 'rownum',
-> @rank := IF(@pre_val != price,@rownum,@rank) as 'rank',
-> @pre_val := price as 'price'
-> from painting order by price;
+--------+------+-------+
| rownum | rank | price |
+--------+------+-------+
| 1 | 1 | 34 |
| 2 | 1 | 34 |
| 3 | 3 | 48 |
| 4 | 3 | 48 |
| 5 | 5 | 64 |
| 6 | 6 | 67 |
+--------+------+-------+
6 rows in set (0.00 sec)



















你可能感兴趣的:(技术)