前两天看到一个sql面试题,发现不太会做,在Javaeye论坛上提问,N多达人进行了回答,个人进行总结归纳一下,以备忘,也可以让大家借鉴一下,很不错。
在数据库中已存在如下表(’pk’表示主键,fk引用pk)
flight(航班信息表) city(城市表)
Flowid (流水号) pk |
orgCityCode(起飞城市编号) fk dstCityCode(到达城市编号) fk flightnum(航班号) deptDateTime(起飞时间) |
cityCode(城市编号) PK |
cityName(城市名称) |
1) 请用SQL语句选出从“北京”出发飞往各地的航班号,并按照到达城市编号排序
2) 请用SQL语句选出2009-6-1以后起飞的航班,并按起飞时间从早到晚排序。输出内容:起飞城市名称、到达城市名称、航班号、起飞时间
3) 请用SQL语句统计2009-6-1至2009-6-10每天从“北京”出发飞往各地的航班的数量。
4) 请用SQL语句找出今天只有去程,没有回程的航线。
----------------------------------------------------------------------------------------------------------------------------------
1)select flightnum from flight f inner join city c
on f.orgCityCode=c.cityCode
where c.cityName='北京'
order by f.dstCityCode
2)推荐使用第二种方法。第一种较复杂,不太容易理解。
select start_flight.startName as startCityName,c2.cityname as endCityName,start_flight.flightnum,start_flight.deptDateTime
from (select f.*,c1.cityname as startName from flight f inner join city c1 on c1.citycode=f.orgCityCode) start_flight
inner join city c2 on start_flight.dstCityCode=c2.cityCode
where start_flight.deptDateTime>cast('2009-06-01' as datetime)
order by start_city.deptDateTime
select c1.cityname,c2.cityname,f.flightnum,f.deptDateTime
from flight f
inner join city c1 on c1.cityCode=f.orgCityCode
inner join city c2 on c2.cityCode=f.dstCityCode
where f.deptDateTime>'2009-06-01'
order by f.deptDateTime
3)
select count(f.flowid)
from flight f inner join city c on f.orgCityCode=c.cityCode
where c.cityName='北京' and f.deptDateTime>=cast('2009-06-01' as datetime) and f.deptDateTime<=cast('2010-06-10' as datetime)
group by convert(varchar(10),f.deptDateTime,23)
4)推荐使用第二种方法较好。第一种方法是一种union all连接,它会把flight所有的字段合在一起两次(有两个flight表),sql的执行效率会很低;第二种使用了一个not exist,很聪明,它只需要进行简单的两次查询就可以得到结果。
select distinct f1.*
from flight f1,flight f2
where f1.orgCityCode!=f2.dstCityCode and f1.dstCityCode!=f2.orgCityCode and convert(char(10),f.deptDateTime,23)=convert(char(10),getdate(),23)
select f.*
from flight f
where convert(char(10),f.deptDateTime,23)=convert(char(10),getdate(),23)
and not exists(select * from train f1 where f.startCode=f1.endCode and f.endCode=f1.startCode)