日期:2014-05-17  浏览次数:20923 次

杭州阿里巴巴第二轮电话面试,被BS好几回,特留此贴以及问题,请大家指点!
大家还记得我8天前发的阿里巴巴一面的帖子吗?过去了一个星期了,我以为事情已经黄了,所以就再也没有做相关准备,结果今天阿里巴巴第二轮笔试电话突然而至,搞的我措手不及啊!

1,如果有row_number() 分析函数,如果我有一张学生表student,里面有班级、学生名、分数,排名我想得到如下数据,该如何用row_number() 排序写一条sql获取,不能用union all来连接获取。
--班级、学生名、分数,排名
  一班 李一 100 1
  一班 李二 100 1
  一班 李三 100 1
  一班 李四 100 4
  一班 李五 99 5
  一班 李六 98 6
.......-- 一班很多学生,依次排下去。
  二班 王一 100 1
  二班 王二 100 1
  二班 王三 99 3
  二班 王四 98 4
  二班 王五 80 5
...... 二班有很多学生,依次排下去。

我的答案是:select banji,name,score,row_number() over(order by banji, name,score desc)。结果他说不对,最近在做sqlserver开发,可能长时间没有碰oracle了,所以导致当时一下没有想出来,被严重BS了,事后仔细一想,其实很简单的,我以前还写过类似的sql,只是时间长了,忘记了,呵呵,不知道大家知道怎么写了么?

2,有关优化的事情,A表500万数据,B表2亿条数据。A与B的数据结构相同,select count(*) from A,B where A.id=B.id。问下,这条sql很耗时,如何优化这条sql,使之效率最高。

我答案,看执行计划,是否走索引,不走的话,就重建所以,他说,如果索引都是完好无损的,而且2亿条数据走索引时优化不过来的,问我还有别的方式来优化这条sql不?我一时就答不出来了,因为sql很简单了,不知道如何优化了,而且我们的oracle库也没有类似的查询,所以一下想不出来怎么回答,结果又被BS了。

3,数据仓库里面,如果你根据客户的需求写完了sql,取到了数据,你如何保证这些数据时准确的呢?

我回答,1,根据需求写一些测试sql来验证,比如数据总量,主要字段,主要信息,抽取几条验证。
  2,找客户,跳一些数据来验证。
结果他反问我这些方法是我自己想出来的吗?我说是的,我感觉我的回答不太对,有点不妙。

还有一些我回答正确的问题,比如管理方面的,我就答的不错,我就不列出来了。反正今天在引以为强项的sql编写与优化上面被问到了,证明我的oracle开发基本功还是很差的,以后要加强这方面的练习了。

欢迎大家对上面的3个问题,发表下自己的看法,在此先行谢过!




 

------解决方案--------------------
我也想知道答案
------解决方案--------------------
LZ,我面试的是一家阿里巴巴的外包公司,也是阿里巴巴的人面试我的,问题跟你差不多啊!!

rownum_over这个没问,第二个问题我是分三个方面回答的,分区、并行、索引,感觉索引这方面回答得有问题,被bs了,不过还是拿到offer了。
阿里巴巴的HR面试水平还是很高的,这种开放式的问题比那种问你知道decode函数什么意思吗之类的SB问题有水平多了。
------解决方案--------------------
先谢谢楼主无私!
SQL code
--1.
with student as(
  select '一班' class,'李一' name, 100 score from dual union all
  select '一班' class,'李二' name, 100 score from dual union all
  select '一班' class,'李三' name, 100 score from dual union all
  select '一班' class,'李四' name, 100 score from dual union all
  select '一班' class,'李五' name, 99  score from dual union all
  select '一班' class,'李六' name, 98  score from dual union all
  select '二班' class,'王一' name, 100 score from dual union all  
  select '二班' class,'王二' name, 100 score from dual union all
  select '二班' class,'王三' name, 99  score from dual union all
  select '二班' class,'王四' name, 98  score from dual union all
  select '二班' class,'王五' name, 80  score from dual),
  tt as(  
  SELECT t.*, row_number() over(PARTITION BY CLASS ORDER BY score DESC) rn FROM student t)
  SELECT a.class, a.name, a.score, b.mrn
    FROM tt a, (SELECT CLASS, score, MIN(rn) mrn FROM tt GROUP BY CLASS, score) b
   WHERE a.class = b.class AND
         a.score = b.score;
--2.先用集合运算不知效率怎样
SELECT COUNT(*)
  FROM (SELECT *
          FROM a
        INTERSECT
        SELECT * FROM b);

------解决方案--------------------
1:直接用DENSE_RANK()函数不是更好?
2:select count(*) from A,B where A.id=B.id。没有执行计划,没有表结构,我的水平还没有到这个程度。。。难道用EXIST做?
3:总数量验证,SQL语句的WHERE条件审查,数据仓库分析结果验证,感觉就这样了,简单的验证。。。。
------解决方案--------------------
1:我觉得用rank()比较好实现排名,不知道row_number()怎么实现这种排名
2:首先从表连接方式,然后分区、并行
3;不知道,我只能说,我在分析需求时,会尽量把问题澄清,不知道此处强调数据仓库,有什么意思

期待高人给出解释
------解决方案--------------------
我也来看看:

1.一班 李一 100 1
一班 李二 100 1
一班 李三 100 1
一班 李四 100 4 (数据有误?这是为啥是4?)

2.select count(*) from A,B where A.id=B.id
这个语句就写法上来说,是最简洁的。
1)假如是OLAP之类的系统,可以使用位图索引(传说中位图索引对COUNT这种运算相当地快)
2) OLTP,2张表都得有索引,fast full scan 2个表的索引再hash join(其中A为驱动表), 速度应该是OK的了。