【函数的使用】 函数定义和调用 在开发程序时,需要多次用到某块代码,为了提高编写效率和代码的复用性,把具有独立功能的代码块组织为一个小模块,称为函数。函数也是各个功能串联的“流水线“模块。类似数学函数f(x),每次传入一个参数x,就可以得到一个函数值y,返回映射要稳定! def 函数名(参数1, 参数2, ……): """函数文档说明文字函数文档说明文字 函数文档说明文字函数文档说明文字""" 代码 函数名(参数) ——调用函数 函数名? ——查看函数文档说明 !调用函数更多时候希望获取返回值;return一旦运行到,函数会直接退出,return后面任何函数内的代码都不会被执行 @函数中最终结果用return返回,调用函数时指给一个定义的变量 要求返回多个值: def test(a,b): c = a+b d = a*b e = a/b return c,d,e #等同于return(c,d,e) test(2,3) (5,6,0.666666666666666) c,d,e = test(3,2) #相当于 c,d,e = 5,6,1.5 c 5 d 6 e 1.5 练习:完成一个函数,功能和sum相同 sum( ) 9 def sum_me(x_list): n = 0 for i in x_list: n += i return n sum_me( ) 9 形参和实参 定义时小括号中的参数,用来接收参数用的,称为形参(因为仅作为一个变量存在,并不是函数运行时候的真实值);调用时小括号中的参数,用来传递给函数用的,称为实参(真正传入进入函数的参数)。 位置参数和关键字参数 位置参数 positional argument test(1,2,3) #1,2,3按顺序依次传递 test(c=3, b=2, a=1) #按关键字传递参数,形参与实参结合 test(1,2,c=3) #可以混合 !但位置参数不能在关键字参数的后面,也就是开始使用关键字参数后就一直继续使用关键字参数 test(a=1,2,3) #报错 默认参数 print(value, …, sep=' ', end='\n', file=sys,stdout,flush=False) def power(x, y=2) #多遇平方,所以可以设置参数y默认为2,调用时作为默认值传入 n = 1 i = 0 while i y: n *= x i += 1 return n power(3) 9 power(2,5) 32 可变长参数 指传入的参数个数时可变的,可以是1个、2个到任意个,也可以是0个,打包成一个tuple元组传进来。 def sum_you(*x_list): *xlist已为可变长参数 n = 0 for i in x_list: n += i return n 可变长关键字参数 允许传入0个或人一个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict字典。 def test (**x): for i in x: print(i, '---', x ) test(a=1, b=2, c='qqq', d=True) d--- True a--- 1 c--- qqq b--- 2 普通参数+可变长参数+可变长关键字参数 def fun(a,b, *args, **kwargs): print("a =", a) print("b=", b) print("args=", args) print("kwargs:") print(kwargs) fun(1,2,3,4,5,m=6,n=7,p=8) a =1 b =2 args = (3,4,5) kwargs: {'m':6, 'n':7, 'p':8} 练习:给定一组数字a,b,c……,请计算a^2+b^2+c^2+…… def calc(*args): sum = 0 for n in args: sum += n*n return sum 【变量的作用域】 局部变量 在函数内部定义的变量。不同的函数,可以定义相同名字的局部变量,但是各个之间不会互相产生影响。作用是为了临时保存数据需要在函数中定义变量来进行存储。 全局变量 既能在一个函数中使用, 也能在其他函数中使用的变量。 全局变量和局部变量名字相同 如果全局变量的名字和局部变量的名字相同,那么优先使用局部变量。(强龙不压地头蛇) 修改全局变量 函数内部可以调用全局变量的值,但是不能修改它 非要在函数内部修改全局变量: a = 1 def f(): global a #在函数内声明,引入全局变量,就可以继续修改 a+= 1 print (a) f() 2 可变类型的全局变量 在函数中不使用global生命全局变量时,不能修改全局变量,本质是不能修改全局变量的指向,即不能将全局变量指向新的数据。 对于不可变类型的全局变量来说,因其指向的数据不能修改,所以不适用global时无法修改全局变量; 对于可变类型的全局变量来说,因其指向的数据可以修改,所以不适用global时也可以修改全局变量。
【SQL查询与函数】 11、 算数操作符(4):+、-、*、/ 比较操作符(9):=、、、=、=、!=或(不等于)、!(不大于)、!(不小于) 12、聚合类函数 AVG:按列计算平均值 SUM:按列计算值的总和 MAX:求一列中的最大值 MIN:求一列中的最小值 COUNT:按列值计数 13、查询SELECT语句:查询指从数据源中提取需要的数据的过程 1)单表查询 SELECT 目标列组 ——即要提取的字段 FROM 数据源——从哪个/哪些数据表来的 ——限定选择条件,where是在分组前对整个数据源进行条件限定 ]——分组及限制分组条件,having是针对group by分组来进行约束的! ];——对查询结果进行排序 e.g. 对大气质量表进行有选择的查询 select city_name, avg(pm25), avg(pm10) from Monthly_Indicator where pm2550 group by city_name, month_key having city_name'北京' order by avg(pm25) desc; @区分group by和聚合函数:group by是分组(类似数据透视表中行列标签下),聚合类函数是按照分组条件来对数据进行汇总计算(类似数据透视表的值里面的) @何时用where何时用group by:在很多情况下两者限定后的执行结果是一样的。一般出现group by就尽可能用having来进行条件限定(一定同时使用,先分组才能分组限定!);如果having限定并不能满足最终的查询需求,此时再考虑使用where;没有group by时用不了having,就只能用where来限定条件 @最后降序排序是desc,升序排序是asc eg1. 查询大气质量表中的全部数据(全选 *) eg2. 查询北京(限定条件)的大气质量数据 eg3. 查询不同月份(分组条件)PM2.5的最大值(聚合函数值) eg4. 降序(排序)查询不同城市(分组条件)PM10的平均值(聚合函数值) 2)多表查询:将两个以上的数据表通过关键字段连接在一起,并从不同表中取不同字段进行查询的方法(实际常见情况) 关键字段:用来连接两表的内容信息能够使其匹配上的字段 - 相连的两表中都需要有关键字段 - 关键字段中的记录信息能够匹配上(名称对不上不要紧) - 最理想的连接状态是两表中的两个关键字段都是主键,而且两个主键的值都能够一一匹配上(避免了空值和重复值),此时用inner/left/right join的结果都一样;实际情况多对一、多对多、有空值、有重复等情况5 - 在连接语句前方的表称为“左表”,后方的表称为“右表”,方向决定了主要参考依据是谁 SELECT select_list FROM 表1 inner/left/right join 表2 on 表1.key = 表2.key @关键字段名只要有重名,就要写明表名;无重名时可以直接写字段名——该规则适用于多表查询中所有字段名表述 14、内连接查询 Inner Join 按照连接条件合并两个表,返回满足条件的行。 SELECT select_list FROM A INNER JOIN B ON A.Key = B.Key e.g. select 学员信息表.*, 学员成绩表.* from 学员信息表 inner join 学员成绩表 on 学员信息表.学号 = 学员成绩表.学号; 15、左连接查询 Left Join 结果中除了包括满足连接条件的行外,还包括左表的所有行。 SELECT select_list FROM A LEFT JOIN B ON A.Key = B.Key e.g. select 学员信息表.*, 学员成绩表.* from 学员信息表 left join 学员成绩表 on 学员信息表.学号 = 学员成绩表.学号; !左表独有部分,右表匹配不上,会在后方列补上空值 16、右连接查询 Left Join 结果中除了包括满足连接条件的行外,还包括右表的所有行。 SELECT select_list FROM A RIGHT JOIN B ON A.Key = B.Key e.g. select 学员信息表.*, 学员成绩表.* from 学员信息表 right join 学员成绩表 on 学员信息表.学号 = 学员成绩表.学号; !右表独有部分,左表匹配不上,也会在前方列补上空值 17、联合查询 Union(即Power Query纵向连接) Union:用于合并两个或多个SELECT语句的结果集,并消去表中任何重复行。 select t1.* from t1 union select t2.* from t2; Union All:用于合并两个或多个SELECT语句的结果集,并保留何重复行。 select t1.* from t1 union all select t2.* from t2; —————————————————————————————————————————————————————— 18、查询操作符:用在SELECT查询语句中,在为查询限定条件时使用 e.g. f_id:水果ID s_id:品类ID(一个品类下有多种不同水果) f_name:水果名称 f_price:水果价格 AND: 用来联合多个条件进行查询,条件与条件间是“和”的关系 条件表达式1 AND 条件表达式2 #用 and 操作符查询s_id为101并且f_id为a1的水果记录 select * from fruits where s_id = 101 and f_id = 'a1'; OR: 用来联合多个条件进行查询,条件与条件间是“或”的关系 条件表达式1 OR 条件表达式2 #用 or 操作符查询苹果或者橙子的相关记录 select * from fruits where f_name = 'apple' or f_name = 'orange'; IN: 判断某个字段的值是否在指定的集合中,如果在集合中,则满足查询条件;如果不在,则不满足查询条件。 IN (元素1,元素2, ... ,元素n) @NOT是可选参数,加上NOT表示不在集合内则满足条件 NOTIN (元素1,元素2, ... ,元素n) #用 in 操作符查询苹果和橙子的相关记录 select * from fruits where f_name in ('apple','orange'); #用 not in 操作符查询苹果和橙子之外的水果的相关记录 select * from fruits where f_name not in ('apple','orange'); BETWEEN: 判断某个字段的值是否在指定的范围内,如果在则满足查询条件;如果不在则不满足查询条件。 BETWEEN 取值1 AND 取值2 @NOT是可选参数,加上NOT表示不在指定范围内则满足条件 NOTBETWEEN 取值1 AND 取值2 #用 between ... and 操作符查询f_price在10元到20元之间的水果记录 select * from fruits where f_price between 10 and 20;——10=x=20 LIKE: 用来匹配字符串是否相等,如果字段的值与指定的字符串相匹配,则满足查询条件;如果与指定的字符串不匹配,则不满足查询条件。 LIKE '字符串' @NOT是可选参数,加上NOT表示指定的字符串不匹配时满足条件。 NOTLIKE '字符串' !字符串参数的值可以是一个完整的字符串,也可以是包含 %(代表任意长度的字符串) 或者 _(仅表示单个字符) 的通配符。 #用 like 操作符查询所有f_id由b开始且字符长度为两位的水果记录 select * from fruits where f_id like 'b_'; IS NULL: 用来判断字段的值是否为空值(NULL),如果字段的值为空值,则满足查询条件;如果字段的值为非空值,则不满足查询条件。—— 常用于验证数据的准确性,是否有空值存在 IS NULL @NOT是可选参数,加上NOT表示字段不是空值时满足条件。 IS NOT NULL #用is null操作符查询所有f_name为空的水果记录 select * from fruits where f_name is null ; DISTINCT: 用来消除重复记录。 SELECT DISTINCT 字段名 #查询fruits表中所有不重复的s_id select distinct s_id from fruits; 19、操作符与子查询的组合应用 子查询:写在()中,把内层查询结果当做外层查询参照的数据表来用,类似Excel函数嵌套 ANY: 表示满足其中任意一个条件,只要满足内层查询语句返回的结果中的任何一个,就可以通过该条件来执行外层查询语句。 #用 any 操作符与子查询语句来查询所有f_id对应的f_price在10元到20元之间的水果记录 select * from fruits where f_id = any (select f_id from fruits where f_price between 10 and 20); ALL: 表示满足所有条件,只有满足内层查询语句返回的所有结果,才可以执行外层查询语句。 #用 all 操作符与子查询语句来查询所有f_price大于20元的水果记录 select * from fruits where f_price all (select f_price from fruits where f_price = 20);——“双重否定等于肯定” EXISTS: 表示存在,内层查询语句返回的不是查询记录,而是一个真假值T/F。如果内层查询语句查询到满足条件的记录(哪怕只有一条就行),就返回真值,否则返回假值;当返回真值时,外层查询语句将进行查询(执行外层查询语句全句,“比较极端”);当返回假值时,外层查询语句不进行查询或者查询不出任何记录。 #用 exists 操作符与子查询语句来查询是否存在f_price大于30元的水果记录 select * from fruits where exists (select * from fruits where f_price 30); 20、as查询中重命名与limit限制查询结果行数 AS: 可以将表或字段名重新命名为别的名称使用, 只在查询中有效 #用 as 将fruits表名重命名为f后使用 select f.* from fruits as f; LIMIT: 查询后只显示limit指定数字的行数结果 #显示f_price金额最大的前三名水果记录 select * from fruits order by f_price desc limit 3; ———————————————————————————————————————————————————————— 21、SQL常用函数 1)常见的数学函数 ABS(x):返回x的绝对值 #使用abs函数求所有水果平均值与最大值差值的绝对值 select abs(avg(f_price)-max(f_price)) from fruits; LOG(x,y):返回x的以y为底的对数 MOD(x,y):返回x/y的模(余数) RAND():返回0到1内的随机值 @可以通过提供一个参数(x),使RAND(x)随机数生成器生成一个指定的值。 CEILING(x):返回大于x的最小整数值(进一取整) ROUND(x,y):返回参数x的四舍五入的有y位小数的值(四舍五入) SQRT(x):返回x的平方根 2)常见的字符串函数 CONCAT(s1,s2, ... ,sn):将s1,s2,…,sn连接成一个字符串 LEFT(str,x):返回字符串str中最左边的x个字符 RIGHT(str,x):返回字符串str中最右边的x个字符 LENGTH(str):返回字符串str中的字符数 #使用length函数求每个f_name的名字与他们的字符长度 select f_name, length(f_name) from fruits group by f_name; 3)常见的日期及时间函数 NOW():返回当前的日期和时间 #使用now函数求当前的日期和时间 select now(); DATE(datetime):返回datetime的日期值 TIME(datetime):返回datetime的时间值 4)其他函数 GROUP_CONCAT(col):返回由属于一组的列值连接组合而成的结果 @常与关键字GROUP BY一起使用,能够将分组后指定的字段值都显示出来 #使用group_concat函数查询不同s_id下对应的所有f_name信息 101 Apple 101 Orange - 101 Apple, Orange SELECT s_id, GROUP_CONCAT(f_name) FROM fruits GROUP BYs_id; CAST():将一个值转换为指定的数据类型 UPDATE ... SET:为字段赋值 UPDATE 表名 SET 字段名 = 值; #使用concat函数在f_name字段值前添加'fruit_'信息 update fruits set f_name = concat('fruit_',f_name) select * from fruits;——查看更新结果 DELETE:删除数据表中的数据 DELETE FROM 表名 !如果省略WHERE则会删除表中所有数据记录 #删除f_id为'b5'的数据记录 delete fromfruits wheref_id = 'b5'; ———————————————————————————————————————————————————————— 【查询练习】 SQL实战中有两类使用方法,一是使用查询回答数据问题,二是使用查询来为今后其他的分析提供完整统一的数据源。 电商数据表E-R图,也称实体-联系图(Entity Relationship Diagram),用来描述现实世界的概念模型。 ex1. 倒序查询卖的金额最多的产品 select goodsid, sum(goodsprice*amout) from orderdetail group by goodsid order bysum(goodsprice*amout) desc; ex2. 查询不同尺码下的产品销售数量 select sizenote, goodsid, sum(amount) from orderdetail left join goodssize on orderdetail.sizeid = goodssize.sizeid group by sizenote, goodsid; @值的来源表作为主要信息提供者,优先设为主表,对其左连接 ex3. 查询不同颜色下的产品销售金额 select colornote, goodsid,sum(goodsprice*amout) as 销售额 from orderdetail left join goodscolor on orderdetail.colorid = goodscolor.colorid group by colornote, goodsid; order by colornote, 销售额 desc;——双层排序 ex4. 查询不同尺码下的不同颜色的产品销售金额 select sizenote, colornote, goodsid,sum(goodsprice*amout) as 销售额 from orderdetail left join goodssize on orderdetail.sizeid = goodssize.sizeid left join goodscolor on orderdetail.colorid = goodscolor.colorid group by sizenote, colornote, goodsid order by sizenote, colornote, 销售额 desc;——多层排序,从前往后逐层排序