1,使用count函数生成摘要
函数函数使用很容易,对于MyISAM表来说count(*)语句很快,但是对于BDB或者InnoDB表来说,尽可能要避免使用它,因为该语句要求执行完整的扫描,速度很慢,解决办法是从information_schema数据库中提取table_rows数目
与if语句搭配使用:
创建视图来简化使用摘要(经常使用摘要的时候):
使用视图:
使用min(),max()也是类似的:
类似的还有sum()和avg()函数生成摘要:
2,使用distinct函数消除重复
3,查找数值相关的最大子和最小值
min(),max()这样的聚类函数并不能在where子句中使用,但是我们会有求类似于最大人口的数值,并且对应的城市名字,可以通过最大人口数值存储在用户定义的变量中,然后将数据行与该变量数值相比较来解决该问题:
还有另外一种方法从包含最小或者最大数值的数据行中选取其他数据列的方法:使用连接,将选择的数据放置到另一张表中,然后将该表与原始表接起来匹配该数值的数据行。
4,将摘要划分为子群
为了更准确找出每个发送者从每个主机发送了多少信息,应该使用两个数据列来划分子群。
这里的count是每个发送者(srcuser)从每个主机(srchost)发送的字数。
对mail表中的数据行针对srcuser进行子群划分,然后显示每个子群中发送的最大的消息的大小和最小的消息的大小
经常出现的一种问题:当使用group by来划分子群时,唯一能选择的子句是划分子群的子句和从子群中计算得到的摘要数值。
红色标记为错误,因为子群划分为name,而显示中存在trav_date不是划分子群的子句和从子群中计算得到的摘要数值,显示与最小最大子群数值相关的数据行通常使用引入连接的技术:
5,使用确定的特性选择组群
where 和having的区别在于having操作在已经选定和划分好子群的的数据行集上,能够对聚类子群进行额外的条件约束。
当然也可以使用别名:
使用having和count确定某一个子群内某项纪录唯一:
也可以使用与联合数值中。例如:为了查找仅仅发送了一个信息的信息发送/接收对,可以在mail表中查找仅仅发生一次的联合:
还可以使用表达式结果分组:
6,分类无类别数据
比如在无重复数据中,例如:
不存在重复的数,故不好使用group by来划分子群。
将人口划分为5个百万量级:?????
7,控制摘要显示顺序
以名字划分子群,以行驶的天数来进行排序:
8,查找最小或最大的摘要数值
min(),max()不能作为其他聚类函数的参数。例如:你很容易查找到每个司机的总行驶英里数:
但是可以先对数据行排序,然后使用limit选择第一个数据行:
9,生成包括摘要和列表的报告
使用pthon生成摘要和列表的报告:
import Cookbook import sys import MySQLdb name_map={} conn=Cookbook.connect() cursor=conn.cursor() cursor.execute(""" select name, count(name),sum(miles) from driver_log group by name """) for(name,days, miles) in cursor.fetchall(): name_map[name]=(days,miles) # 选择每个司机的行程数并打印报告,显示行程列表中每个司机的摘要汇总项 cursor.execute(""" select name, trav_date, miles from driver_log group by name, trav_date """) cur_name="" for (name, trav_date, miles) in cursor.fetchall(): if cur_name !=name: print "Name: %s; days on road: %d; miles drien:%d " %(name, name_map[name][0],name_map[name][1]) cur_name=name print "date:%s, trip length:%d "%(trav_date,miles) cursor.close()