前言
- PS:学了这么久编程也是时候开始写一写一些笔记,心得啥的,也算是记录一下自己的成长经历了。
当初大学的时候,学的很杂各种C,JAVA,JS,R,SPSS,SAS,Android都有接触到也学了一点,纯粹是为了应付考试,学了就算了,基本上不会想着以后要干嘛,要咋滴。后来经过了社会的毒打,发现不学点技术那真是完蛋,从此走上了Python的不归路。
后来自学了Python比较长的一段时间了,但是SQL还是停留在上学那个时候的状态,结果对SQL只有模糊的印象,只会最最基本的select,甚至增删改都记不太清楚,以至于简简单单的增加语句:
insert into table(a, b, c) values(d, e, f);
都能写成:
insert table(a, b, c) into values(d, e, f);
之前总想着SQL只是用到普普通通的查询就好了,把查询到的所有数据读进来,然后用Python处理不就好了。
con = create_engine('mysql+pymysql://root:password@localhost:3306/database')
sql = 'select * from table'
df = pd.read_sql(sql, con=con)
但是,如果涉及到了数据量大的时候,这种方式是不可取的。
- 首先Python读取数据库不可避免的一个问题就是占用内存,数据量过大就很容易出现OOM,因为你现在是将整一个表存到内存当中,这无疑会过度占用内存空间的。
- 如果仅仅是一个查询需求,那么使用Python会显得代码量有些臃肿了,毕竟不管怎么样都是要导入包、登录数据库、使用loc、apply等等函数的,而相对来说SQL直接查询就显得更加简便而且快速。
- 以及不是所有的数据库机器都装有Python的,为了自己的技术便利给机器装一个Python通常也是难以被允许的。
到了去面试的时候,一做笔试题,那才叫一个抓鸡。真·书到用时方恨少啊。
SQL实现行列转置
印象特别深的一道题就是将table_1转换成table_2的形式。
table_1:
id | year | month | sal |
---|---|---|---|
1 | 2021 | 1 | 11 |
2 | 2021 | 2 | 12 |
3 | 2021 | 3 | 13 |
4 | 2021 | 4 | 14 |
5 | 2021 | 5 | 15 |
6 | 2021 | 6 | 16 |
7 | 2020 | 1 | 111 |
8 | 2020 | 2 | 112 |
9 | 2020 | 3 | 113 |
10 | 2020 | 4 | 114 |
11 | 2020 | 5 | 115 |
12 | 2020 | 6 | 116 |
table_2:
year | m1 | m2 | m3 | m4 | m5 | m6 |
---|---|---|---|---|---|---|
2021 | 11 | 12 | 13 | 14 | 15 | 16 |
2020 | 111 | 112 | 113 | 114 | 115 | 116 |
是不是很简单,而且难度也很低,但是当时就是不会啊,脚趾头都把鞋抓烂了。
好了直接贴代码(MySQL):
识别一下有没有同名的,有就删掉原表:
drop table if exists table_1;
创建表:
create table table_1(
id int(10) primary key,
syear int(10),
smonth int(10),
sal int(20)
);
插入table_1的数据:
insert into table_1(id, syear, smonth, sal) values(1, 2021, 1, 11);
insert into table_1(id, syear, smonth, sal) values(2, 2021, 2, 12);
insert into table_1(id, syear, smonth, sal) values(3, 2021, 3, 13);
insert into table_1(id, syear, smonth, sal) values(4, 2021, 4, 14);
insert into table_1(id, syear, smonth, sal) values(5, 2021, 5, 15);
insert into table_1(id, syear, smonth, sal) values(6, 2021, 6, 16);
insert into table_1(id, syear, smonth, sal) values(7, 2020, 1, 111);
insert into table_1(id, syear, smonth, sal) values(8, 2020, 2, 112);
insert into table_1(id, syear, smonth, sal) values(9, 2020, 3, 113);
insert into table_1(id, syear, smonth, sal) values(10, 2020, 4, 114);
insert into table_1(id, syear, smonth, sal) values(11, 2020, 5, 115);
insert into table_1(id, syear, smonth, sal) values(12, 2020, 6, 116);
查询一下看看结果:
select * from table_1;
接下来就是重头戏了:
主要的思想其实是,当 smonth = 1 的时候查询对应的sal作为一列,同理 smonth = 2 的时候也是一样的。
那么这个时候可以用到
case when a = '1' then b else c end
来解决这个问题,case when其实可以理解为当…就…不然,当列a的值=1,就输出b,不然就输出c,结束。
所以查询语句可以写成:
select syear as year,
sum(case when smonth = 1 then sal end) as m1,
sum(case when smonth = 2 then sal end) as m2,
sum(case when smonth = 3 then sal end) as m3,
sum(case when smonth = 4 then sal end) as m4,
sum(case when smonth = 5 then sal end) as m5,
sum(case when smonth = 6 then sal end) as m6
from table_1
group by year;
结果:
终于一道SQL的面试题就这样结束了。