开篇——SQL面试题痛的领悟

前言

  • 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)

但是,如果涉及到了数据量大的时候,这种方式是不可取的。

  1. 首先Python读取数据库不可避免的一个问题就是占用内存,数据量过大就很容易出现OOM,因为你现在是将整一个表存到内存当中,这无疑会过度占用内存空间的。
  2. 如果仅仅是一个查询需求,那么使用Python会显得代码量有些臃肿了,毕竟不管怎么样都是要导入包、登录数据库、使用loc、apply等等函数的,而相对来说SQL直接查询就显得更加简便而且快速。
  3. 以及不是所有的数据库机器都装有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;

开篇——SQL面试题痛的领悟
接下来就是重头戏了:
主要的思想其实是,当 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面试题痛的领悟
终于一道SQL的面试题就这样结束了。

上一篇:Oracle第七课


下一篇:《张三记录-java》mysql