数据库的一些常见面试题及其答案详解

我先标明下面题目的转载地址:原题目地址, 还有就是我所使用的数据库是MySQL,但是SQL语法大部分相同,只有少部分与Oracle、SQL Server不同。

之前因为面试中吃了很多SQL 语法的亏了,决定真的要把这个玩会了,之前确实一直因为使用的都是hibernate框架,对数据库原生SQL的操作太少了,所以现在对基本的查询方式特别陌生。看到这套题目之后我还是觉得挺好的,最好是自己亲自写,不会的可以先看一下资料,了解基本的SQL 92 与 SQL 99语法以及数据库分组和组函数之后再开始做题。如果一上来就直接看我的步骤和答案,可能没效果,因为你可能过两天就还给我了。好了,不说那么多了,直接上菜吧:

1、

教师号  星期号 是否有课

 1    2   有

 1    3   有

 2    1   有

 3    2   有`

 1    2   有

写一条sql语句让你变为这样的表

教师号 星期一 星期二 星期三

 1       2   1 

 2   1   

 3       1

解析步骤:首先建表,这里是我建的表:

建表

然后也可看到我图中后面的步骤(以teacher_id列进行升序排序),其实mysql自动就是升序排列。再对比题目要求,我们还需要对calendar列进行操作,对相同数值的行进行count(*)操作,但是要注意的是这个count操作是在我们现有执行上面这样操作之后的数据表,也就是要用到子查询。所以接下来执行如下(这里只是对calendar进行count操作):

仅对calendar进行count操作

仔细看这张表发现在calendar=2时总共有3节课,但是显示的全是teacher_id为1的老师,显然这个是错误的。这是因为我们需要的结果是:哪个老师哪一天有几节课,而上面只有参数哪一天而忽略了哪个老师这个条件,所以这里对后面group by新增一个条件:

增加teacher_id条件

这个看起来差不多了,但是看起来还是乱糟糟的,感觉还是以老师(teacher_id)来排序比较好,所以这里再新增一个条件:

以老师排序

嗯!这个看起来还不错的样子。我觉得这个应该也是答案吧。


因为昨天晚上想着第二道题都到两点了,所以没继续写下去,今天补充上来。

2、

两个表情况

表名:wu_plan 

ID      plan      model       corp_code     plannum     prixis

1       00001     exx22         nokia        2000         0

2       00002     lc001         sony         3000         0

表名:wu_bom

ID     plan       pact          amount    

1      00001      aa1            300

2      00001      aa2            200

3      00002      bb1            500

4      00002      bb2            800

5      00002      bb3            400

查询这两个表中plan唯一,每一个plan中,amount最少的,plannum大于prixis的记录

结果是:

ID      plan      model       corp_code     plannum     prixis     pact   amount

1       00001     exx22         nokia        2000         0       a2       200

2       00002     lc001         sony         3000         0       bb3      400


这道题说实话还是有一些难度的,如果对join操作不熟悉的话,真不好解答,我现在这里push出我参考的一道题目: select first row in each group by group
解题步骤 :要查找amount最少的,肯定要用到SQL的min函数了,然后我们现不看wu_plan,直接对wu_bom表进行操作:
mysql> select min(b.amount) as min_amount, b.plan from wu_bom b group by b.plan;
结果如下图:
每个group中的最小amount
这里可能有些人有点不理解为什么不直接使用min(b.amount)后面要加上一个别名(min_amount)呢?因为这个min_amount在后面要作为我们与表wu_plan比较的根据,如果不设置别名,列名写起来太麻烦了。那么由上面sql 生成了每一组plan中的最小值,但是只有这么一个最小值还是不行的啊,因为题目的条件是每个wu_plan表中的最小数据,我们现在只是wu_bom表啊,那么这时候需要进行: 右连接+子查询
很多人可能会问为什么是这样的操作呢?因为我们现在已经得到了上图这样的一个查询视图,条件也已经知道了(wu_plan中所有plan值为‘00001’的列行与‘00002’的行),这不就是一次右查询的事嘛,我知道这里我说的很不清楚,但是左右查询网上有很多教程的,不熟悉的朋友还是好好看看吧。
下一步:
select p.*,y.min_amount from wu_plan p right join (select min(b.amount) as min_amount, b.plan from wu_bom b group by b.plan) y on p.plan = y.plan and p.plannum > p.prixis;
真相就出来了吧。结果如下图:
查询结果
当然有些同学又会说为什么我在这个表中看到的全是wu_plan表信息,我要想增加wu_bom表信息(比如说增加pact列)怎么办,直接在子查询(SQL语句中括号内增加你想要在结果看到的列)增加该列到县市结果中就可了。

未完待续!

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值