sql 一些题目

这道SQL笔试题你会怎么写(转)

最近面试了一些Senior BI的候选人,行业经验三年到七年不等,起初觉得这个Level的无需准备笔试题,碍于领导执念,就在真实项目中提取5道SQL题目,这里仅单说其中一道难度中等偏下的题目,抛开面试不谈,单看笔试的话几轮下来答题情况并不理想,至今没有发现有人能写出逻辑滴水不漏又性能最大化的脚本,难点的题目甚至还有交白卷的情况,如果看官觉得这仅仅是茴香豆的茴几种写法的问题就飘过吧,我想通过题目考察的并非只是SQL的熟练程度,相对而言更看重候选人对数据的敏感程度,以及脚本性能的优化能力,往深了说就是要了解数据库存储引擎及查询优化器的工作原理,这是一个合格的BI从业者应有的基本素质。

题目是这样的,有一张ER图描述数据结构,这里就不贴图了,简单文字描述如下,劳烦看官各种脑补主外键关系:

一张会员表(account),字段有会员id(account_id), 会员卡号(account_num)。。。

一张交易订单表(trans),字段有会员id(account_id),交易时间(trans_time),交易金额(sales)。。。

要求查询出所有首笔订单的金额超过1000的会员卡号及其首笔订单金额,

注:

1. 首笔订单指的是每个会员交易时间最小的一笔订单

2. 会员表有一千万笔记录

3. 如果会员没有任何订单或者首笔订单金额<=1000,则首笔订单金额返回0。

下面提供三例典型的答题脚本供参考,候选人BI经验分别是三年,四年,六年,脚本笔录风格太过任性,因为题目没有约束DB产品,所以有使用各种DB私有函数的,有使用join的旧式写法的,甚至还有使用CTE的,状况百出,为照顾看官心情,在尊重原著本意的原则下梳理后的TSQL脚本如下:

A

select a.account_number, t.sales

from Account a

join

(

    select account_id, sales, min(trans_time)

    from trans

    group by trans_id

    having sum(sales)>1000

) t on a.account_id=t.account_id

B

select a.account_number, t.sales, rank() over(partition by a.account_id order by t.trans_time) rn

from account a

join trans t on a.account_id=t.account_id

where rn=1 and t.sales>1000

group by a.account_number,t.trans_time

C

Select a.account_number, t.sales

From Account a

left join

(

    Select account_id,sales,row_number() over(order by trans_time) rn

    From Trans

) t on a.account_id=t.account_id

where t.rn=1 and t.sales>1000

------------------------------------------------2014-12-05---------------------------------------------------------

虽然极力想要表达的是思维的严谨性,但经园友提醒还是发现真要是抠字眼的话,题目的描述也还是有不严谨的地方,例如第三个条件里说的首笔订单金额不足1000,竟然把等于1000这种情况漏掉了,目前为止统计答题情况如下:

想说点啥呢,我相信大家在机调试的话都能写出逻辑正确的代码,但很多场合下没有时间允许你反复调试代码,甚至有些逻辑错误是无法调试出来的,SQL里的row_number, where, order到底谁先执行,left join 后面的条件写在on后面还是where后面,不经意的写出来都可能是潜在bug,首先得保证数据逻辑正确无误,性能虽是次要,但糟糕的代码积累多了尾大不掉很容易拖垮整个DB,也是要格外小心的事情。

http://www.cnblogs.com/xpivot/p/4143069.html#!comments

时间: 2024-11-09 09:48:06

sql 一些题目的相关文章

几道经典的SQL笔试题目

几道经典的SQL笔试题目(有答案) (1)表名:购物信息 购物人      商品名称     数量 A            甲          2 B            乙          4 C            丙          1 A            丁          2 B            丙          5 …… (其他用户实验的记录大家可自行插入) 给出所有购入商品为两种或两种以上的购物人记录 答:select * from 购物信息 wher

SQL 面试题目及答案

SQL 面试题目及答案 By Lee - Last updated: 星期五, 五月 31, 2013 Leave a Comment 学生成绩表(stuscore):姓名:name     课程:subject     分数:score     学号:stuid张三     数学     89     1张三     语文     80     1张三     英语     70     1李四     数学     90     2李四     语文     70     2李四     英

SQL面试题目

Student(S#,Sname,Sage,Ssex) 学生表Course(C#,Cname,T#) 课程表SC(S#,C#,score) 成绩表Teacher(T#,Tname) 教师表 问题:1.查询“001”课程比“002”课程成绩高的所有学生的学号:select a.S#from (select s#,score from SC where C#=’001′) a,(select s#,score from SC where C#=’002′) bwhere a.score>b.scor

sql基础题目测试及正确答案

在网上做了一套基本的sql题目,以下是我的写的答案,适合基础人员练练 --创建测试数据 use test create table Student(S# varchar(10),Sname nvarchar(10),Sage datetime,Ssex nvarchar(10)) insert into Student values('01' , N'赵雷' , '1990-01-01' , N'男') insert into Student values('02' , N'钱电' , '199

Oracle sql 复习题目总结

sql 题目一 表结构 1.表名:g_cardapply 字段(字段名/类型/长度): apply_no varchar8; //申请单号(关键字) apply_date date; //申请日期 state varchar2; //申请状态 2.表名:g_cardapplydetail 字段(字段名/类型/长度): apply_no varchar8; //申请单号(关键字) name varchar30; //申请人姓名 idcard varchar18; //申请人身份证号 state v

SQL 面试题目汇总

1.触发器的作用? 答:触发器是一中特殊的存储过程,主要是通过事件来触发而被执行的.它可以强化约束,来维护数据的完整性和一致性,可以跟踪数据库内的操作从而不允许未经许可的更新和变化.可以联级运算.如,某表上的触发器上包含对另一个表的数据操作,而该操作又会导致该表触发器被触发. 2.什么是存储过程?用什么来调用? 答:存储过程是一个预编译的SQL语句,优点是允许模块化的设计,就是说只需创建一次,以后在该程序中就可以调用多次.如果某次操作需要执行多次SQL,使用存储过程比单纯SQL语句执行要快.可以

SQL练习题目(MySQL)

有如下员工表employee: 建表sql为: CREATE TABLE `employee` ( `id` int(11) NOT NULL, `name` varchar(50) DEFAULT NULL, `salary` int(11) DEFAULT NULL, `deptid` int(11) DEFAULT NULL, `age` int(11) DEFAULT NULL, PRIMARY KEY (`id`) 1.查出每个部门高于部门平均工资的员工名单 select a.dept

sql查询题目

--1.查询在1981年入职的员工信息select * from emp where hiredate between '01-1月-1981'and '31-12月-1981'; select * from empwhere hiredate >= '01-1月-1981'and hiredate <='31-12月-1981';--2.查询经理编号不是7902的员工select * from empwhere mgr != 7902; select * from empwhere mgr

SQL练习题题目

基本语法*********************************************************************************************************1. 打印员工号为186的员工的last_name值 declare v_last_name employees.last_name%type;begin select last_name into v_last_name from employees where EMPLOYEE