我的Sql常见面试题(总结)

标签: sql 常见 面试 | 发表时间:2012-11-03 20:14 | 作者:jhl52771
出处:http://blog.csdn.net
我开的  DBA群:225982985

1.用一条SQL语句 查询出每门课都大于80分的学生姓名


name   kecheng   fenshu
张三
语文      81
张三
数学      75
李四
语文      76
李四
数学      90
王五
语文      81
王五
数学      100
王五
英语      90


A: select distinct name from table  where  name not in (selectdistinct name from table where fenshu<=80)


2.学生表 如下:
自动编号
学号
姓名 课程编号课程名称 分数
1        2005001  张三 0001      数学    69
2        2005002  李四 0001      数学    89
3        2005001  张三 0001      数学    69
删除除了自动编号不同,其他都相同的学生冗余信息


A: delete tablename where 自动编号 not in(select min(自动编号) from tablename group by 学号,姓名,课程编号,课程名称,分数)


一个叫department的表,里面只有一个字段name,一共有4条纪录,分别是a,b,c,d,对应四个球对,现在四个球对进行比赛,用一条sql语句显示所有可能的比赛组合.
你先按你自己的想法做一下,看结果有我的这个简单吗?


答:selecta.name, b.name 
from team a, team b 
where a.name < b.name




请用SQL语句实现:从TestDB数据表中查询出所有月份的发生额都比101科目相应月份的发生额高的科目。请注意:TestDB中有很多科目,都有1-12月份的发生额。
AccID:科目代码,Occmonth:发生额月份,DebitOccur:发生额。
数据库名:JcyAudit,数据集:Select * from TestDB


答:select a.*
from TestDB a 
,(select Occmonth,max(DebitOccur) Debit101ccur from TestDB where AccID='101'group by Occmonth) b
where a.Occmonth=b.Occmonth and a.DebitOccur>b.Debit101ccur


*********************************www.52mvc.com***************************************************


面试题:怎么把这样一个表儿
year  month amount
1991   1     1.1
1991   2     1.2
1991   3     1.3
1991   4     1.4
1992   1     2.1
1992   2     2.2
1992   3     2.3
1992   4     2.4
查成这样一个结果
year m1  m2  m3  m4
1991 1.1 1.2 1.3 1.4
1992 2.1 2.2 2.3 2.4 


答案一、
select year, 
(select amount from  aaa m where month=1  andm.year=aaa.year) as m1,
(select amount from  aaa m where month=2  andm.year=aaa.year) as m2,
(select amount from  aaa m where month=3  andm.year=aaa.year) as m3,
(select amount from  aaa m where month=4  andm.year=aaa.year) as m4
from aaa  group by year




这个是ORACLE  中做的:
select * from (select name, year b1, lead(year) over
(partition by name order by year) b2, lead(m,2) over(partition by name order byyear) b3,rank()over(
partition by name order by year) rk from t) where rk=1;


************************************************************************************


精妙的SQL语句!
精妙SQL语句
作者:不详 发文时间:2003.05.29 10:55:05 


说明:复制表(只复制结构,源表名:a 新表名:b) 


SQL: select * into b from a where 1<>1 


说明:拷贝表(拷贝数据,源表名:a 目标表名:b) 


SQL: insert into b(a, b, c) select d,e,f from b; 


说明:显示文章、提交人和最后回复时间 


SQL: select a.title,a.username,b.adddate from table a,(select max(adddate)adddate from table where table.title=a.title) b 


说明:外连接查询(表名1:a 表名2:b) 


SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c 


说明:日程安排提前五分钟提醒


SQL: select * from 日程安排 where datediff('minute',f开始时间,getdate())>5 


说明:两张关联表,删除主表中已经在副表中没有的信息 


SQL: 


delete from info where not exists ( select * from infobz whereinfo.infid=infobz.infid ) 


说明:-- 


SQL: 


SELECT A.NUM, A.NAME, B.UPD_DATE, B.PREV_UPD_DATE 


FROM TABLE1, 


(SELECT X.NUM, X.UPD_DATE, Y.UPD_DATE PREV_UPD_DATE 


FROM (SELECT NUM, UPD_DATE, INBOUND_QTY, STOCK_ONHAND 


FROM TABLE2 


WHERE TO_CHAR(UPD_DATE,'YYYY/MM') = TO_CHAR(SYSDATE, 'YYYY/MM')) X, 


(SELECT NUM, UPD_DATE, STOCK_ONHAND 


FROM TABLE2 


WHERE TO_CHAR(UPD_DATE,'YYYY/MM') = 


TO_CHAR(TO_DATE(TO_CHAR(SYSDATE, 'YYYY/MM') ¦¦ '/01','YYYY/MM/DD') - 1,'YYYY/MM') ) Y, 


WHERE X.NUM = Y.NUM (+) 


AND X.INBOUND_QTY + NVL(Y.STOCK_ONHAND,0) <> X.STOCK_ONHAND ) B 


WHERE A.NUM = B.NUM 


说明:-- 


SQL: 


select * from studentinfo where not exists(select * from student wherestudentinfo.id=student.id) and 系名称='"&strdepartmentname&"' and 专业名称='"&strprofessionname&"'order by 性别,生源地,高考总成绩
说明:
从数据库中去一年的各单位电话费统计(电话费定额贺电化肥清单两个表来源) 


SQL: 


SELECT a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate, 'yyyy') AS telyear, 


SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '01', a.factration)) AS JAN, 


SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '02', a.factration)) AS FRI, 


SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '03', a.factration)) AS MAR, 


SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '04', a.factration)) AS APR, 


SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '05', a.factration)) AS MAY, 


SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '06', a.factration)) AS JUE, 


SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '07', a.factration)) AS JUL, 


SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '08', a.factration)) AS AGU, 


SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '09', a.factration)) AS SEP, 


SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '10', a.factration)) AS OCT, 


SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '11', a.factration)) AS NOV, 


SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '12', a.factration)) AS DEC 


FROM (SELECT a.userper, a.tel, a.standfee, b.telfeedate, b.factration 


FROM TELFEESTAND a, TELFEE b 


WHERE a.tel = b.telfax) a 


GROUP BY a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate, 'yyyy') 


说明:四表联查问题: 


SQL: select * from a left inner join b on a.a=b.b right inner join c on a.a=c.cinner join d on a.a=d.d where ..... 


说明:得到表中最小的未使用的ID号 


SQL: 


SELECT (CASE WHEN EXISTS(SELECT * FROM Handle b WHERE b.HandleID = 1) THENMIN(HandleID) + 1 ELSE 1 END) as HandleID 


FROM Handle 


WHERE NOT HandleID IN (SELECT a.HandleID - 1 FROM Handle a)




*******************************************************************************


有两个表A和B,均有key和value两个字段,如果B的key在A中也有,就把B的value换为A中对应的value
这道题的SQL语句怎么写?


update   b   set  b.value=(select   a.value   from   a   where  a.key=b.key)   where   b.id   in(select   b.id   from  b,a   where   b.key=a.key);


***************************************************************************


高级sql面试题


原表: 
courseid coursename score 
------------------------------------- 
1 java 70 
2 oracle 90 
3 xml 40 
4 jsp 30 
5 servlet 80 
------------------------------------- 
为了便于阅读,查询此表后的结果显式如下(及格分数为60): 
courseid coursename score mark 
--------------------------------------------------- 
1 java 70 pass 
2 oracle 90 pass 
3 xml 40 fail 
4 jsp 30 fail 
5 servlet 80 pass 
--------------------------------------------------- 
写出此查询语句


没有装ORACLE,没试过 
select courseid, coursename ,score ,decode(sign(score-60),-1,'fail','pass') as mark from course


完全正确 


SQL> desc course_v 
Name Null? Type 
----------------------------------------- -------- ----------------------------
COURSEID NUMBER 
COURSENAME VARCHAR2(10) 
SCORE NUMBER 


SQL> select * from course_v; 


COURSEID COURSENAME SCORE 
---------- ---------- ---------- 
1 java 70 
2 oracle 90 
3 xml 40 
4 jsp 30 
5 servlet 80 


SQL> select courseid, coursename ,score,decode(sign(score-60),-1,'fail','pass') as mark from course_v; 


COURSEID COURSENAME SCORE MARK 
---------- ---------- ---------- ---- 
1 java 70 pass 
2 oracle 90 pass 
3 xml 40 fail 
4 jsp 30 fail 
5 servlet 80 pass


*******************************************************************************


原表: 


id proid proname 
1 1 M 
1 2 F 
2 1 N 
2 2 G 
3 1 B 
3 2 A 
查询后的表: 


id pro1 pro2 
1 M F 
2 N G 
3 B A 
写出查询语句


解决方案 


sql求解
表a 
列 a1 a2 
记录 1 a 
1 b 
2 x 
2 y 
2 z 
用select能选成以下结果吗? 
1 ab 
2 xyz 
使用pl/sql代码实现,但要求你组合后的长度不能超出oracle varchar2长度的限制。
下面是一个例子 
create or replace type strings_table is table of varchar2(20); 

create or replace function merge (pv in strings_table) return varchar2 
is 
ls varchar2(4000); 
begin 
for i in 1..pv.count loop 
ls := ls || pv(i); 
end loop; 
return ls; 
end; 

create table t (id number,name varchar2(10)); 
insert into t values(1,'Joan'); 
insert into t values(1,'Jack'); 
insert into t values(1,'Tom'); 
insert into t values(2,'Rose'); 
insert into t values(2,'Jenny'); 


column names format a80; 
select t0.id,merge(cast(multiset(select name from t where t.id = t0.id) asstrings_table)) names 
from (select distinct id from t) t0; 


drop type strings_table; 
drop function merge; 
drop table t; 








用sql: 


Well if you have a thoretical maximum, which I would assume you would given thelegibility of listing hundreds of employees in the way you describe then yes.But the SQL needs to use the LAG function for each employee, hence a hundredemps a hundred LAGs, so kind of bulky. 


This example uses a max of 6, and would need more cut n pasting to do more thanthat. 


SQL> select deptno, dname, emps 
2 from ( 
3 select d.deptno, d.dname, rtrim(e.ename ||', '|| 
4 lead(e.ename,1) over (partition by d.deptno 
5 order by e.ename) ||', '|| 
6 lead(e.ename,2) over (partition by d.deptno 
7 order by e.ename) ||', '|| 
8 lead(e.ename,3) over (partition by d.deptno 
9 order by e.ename) ||', '|| 
10 lead(e.ename,4) over (partition by d.deptno 
11 order by e.ename) ||', '|| 
12 lead(e.ename,5) over (partition by d.deptno 
13 order by e.ename),', ') emps, 
14 row_number () over (partition by d.deptno 
15 order by e.ename) x 
16 from emp e, dept d 
17 where d.deptno = e.deptno 
18 ) 
19 where x = 1 
20 / 


DEPTNO DNAME EMPS 
------- ----------- ------------------------------------------ 
10 ACCOUNTING CLARK, KING, MILLER 
20 RESEARCH ADAMS, FORD, JONES, ROONEY, SCOTT, SMITH 
30 SALES ALLEN, BLAKE, JAMES, MARTIN, TURNER, WARD 


also 
先createfunction get_a2; 
create or replace function get_a2( tmp_a1 number) 
return varchar2 
is 
Col_a2 varchar2(4000); 
begin 
Col_a2:=''; 
for cur in (select a2 from unite_a where a1=tmp_a1) 
loop 
Col_a2=Col_a2||cur.a2; 
end loop; 
return Col_a2; 
end get_a2; 


select distinct a1 ,get_a2(a1) from unite_a 
1 ABC 
2 EFG 
3 KMN


*******************************************************************************


一个SQL 面试题


去年应聘一个职位未果,其间被考了一个看似简单的题,但我没有找到好的大案.
不知各位大虾有无好的解法?




题为:
有两个表, t1, t2,
Table t1:


SELLER | NON_SELLER
----- -----


A B
A C
A D
B A
B C
B D
C A
C B
C D
D A
D B
D C




Table t2:


SELLER | COUPON | BAL
----- --------- ---------
A 9 100
B 9 200
 C 9 300
D 9 400
 A 9.5 100
B 9.5 20
 A 10 80






要求用SELECT 语句列出如下结果:------如A的SUM(BAL)为B,C,D的和,B的SUM(BAL)为A,C,D的和.......
且用的方法不要增加数据库负担,如用临时表等.


NON-SELLER| COUPON | SUM(BAL) ------- --------
A 9 900
B 9 800
 C 9 700
D 9 600 
 A 9.5 20
B 9.5 100
 C 9.5 120
D 9.5 120
 A 10 0
B 10 80
 C 10 80
D 10 80


关于论坛上那个SQL微软面试题


问题:
一百个账户各有100$,某个账户某天如有支出则添加一条新记录,记录其余额。一百天后,请输出每天所有账户的余额信息
这个问题的难点在于每个用户在某天可能有多条纪录,也可能一条纪录也没有(不包括第一天)
返回的记录集是一个100天*100个用户的纪录集
下面是我的思路:


1.创建表并插入测试数据:我们要求username从1-100
CREATE TABLE [dbo].[TABLE2] (
[username] [varchar] (50) NOT NULL , --用户名
[outdate] [datetime] NOT NULL , --日期
[cash] [float] NOT NULL --余额
) ON [PRIMARY


declare @i int
set @i=1
while @i<=100
  begin
    insert table2 values(convert(varchar(50),@i),'2001-10-1',100)
    insert table2 values(convert(varchar(50),@i),'2001-11-1',50)
    set @i=@i+1
  end
insert table2 values(convert(varchar(50),@i),'2001-10-1',90)


select * from table2 order by outdate,convert(int,username)


2.组合查询语句:
a.我们必须返回一个从第一天开始到100天的纪录集:
如:2001-10-1(这个日期是任意的) 到 2002-1-8
由于第一天是任意一天,所以我们需要下面的SQL语句:
select top 100 dateadd(d,convert(int,username)-1,min(outdate)) as outdate
from table2
group by username
order by convert(int,username)
这里的奥妙在于:
convert(int,username)-1(记得我们指定用户名从1-100 :-))
group by username,min(outdate):第一天就可能每个用户有多个纪录。
返回的结果:
outdate                                              
------------------------------------------------------ 
2001-10-01 00:00:00.000
.........
2002-01-08 00:00:00.000


b.返回一个所有用户名的纪录集:
select distinct username from table2 
返回结果:
username                                         
-------------------------------------------------- 
1
10
100
......
99


 c.返回一个100天记录集和100个用户记录集的笛卡尔集合:
select * from
(
select top 100 dateadd(d,convert(int,username)-1,min(outdate)) as outdate
from table2
group by username
order by convert(int,username)


) as A
CROSS join 
(
select distinct username from table2 
) as B
order by outdate,convert(int,username)
返回结果100*100条纪录:
outdate                           username
2001-10-01 00:00:00.000            1
......
2002-01-08 00:00:00.000            100


d.返回当前所有用户在数据库的有的纪录:
select outdate,username,min(cash) as cash from table2
group by outdate,username


order by outdate,convert(int,username)
返回纪录:
outdate                           username    cash
2001-10-01 00:00:00.000            1         90
......
2002-01-08 00:00:00.000            100       50


e.将c中返回的笛卡尔集和d中返回的纪录做left join:
select C.outdate,C.username,
D.cash
from
(
select * from
(
select top 100 dateadd(d,convert(int,username)-1,min(outdate)) as outdate
from table2
group by username
order by convert(int,username)
) as A
CROSS join 
(
select distinct username from table2 
) as B
) as C
left join
(
select outdate,username,min(cash) as cash from table2
group by outdate,username
) as D
on(C.username=D.username and datediff(d,C.outdate,D.outdate)=0)


order by C.outdate,convert(int,C.username)
注意:用户在当天如果没有纪录,cash字段返回NULL,否则cash返回每个用户当天的余额
outdate                           username    cash
2001-10-01 00:00:00.000            1         90
2001-10-01 00:00:00.000            2         100
......
2001-10-02 00:00:00.000            1         90


2001-10-02 00:00:00.000           2          NULL  <--注意这里
......


2002-01-08 00:00:00.000            100       50


f.好了,现在我们最后要做的就是,如果cash为NULL,我们要返回小于当前纪录日期的第一个用户余额(由于我们使用order by cash,所以返回top 1纪录即可,使用min应该也可以),这个余额即为当前的余额:
case isnull(D.cash,0)
when 0 then 
(
select top 1 cash from table2 where table2.username=C.username
and datediff(d,C.outdate,table2.outdate)<0 
order by table2.cash
)
else D.cash
end as cash


g.最后组合的完整语句就是
select C.outdate,C.username,
case isnull(D.cash,0)
when 0 then 
(
select top 1 cash from table2 where table2.username=C.username
and datediff(d,C.outdate,table2.outdate)<0 
order by table2.cash
)
else D.cash
end as cash
from
(
select * from
(
select top 100 dateadd(d,convert(int,username)-1,min(outdate)) as outdate
from table2
group by username
order by convert(int,username)
) as A
CROSS join 
(
select distinct username from table2 
) as B
) as C
left join
(
select outdate,username,min(cash) as cash from table2
group by outdate,username
) as D
on(C.username=D.username and datediff(d,C.outdate,D.outdate)=0)


order by C.outdate,convert(int,C.username)


返回结果:
outdate                               username        cash
2001-10-01 00:00:00.000    1                   90
2001-10-01 00:00:00.000    2                  100
......
2002-01-08 00:00:00.000   100               50


***********************************************************************************


取出sql表中第31到40的记录(以自动增长ID为主键)


*从数据表中取出第n条到第m条的记录*/ 


declare @m int 
declare @n int 
declare @sql varchar(800) 
set @m=40 
set @n=31 
set @sql='select top '+str(@m-@n+1) + '* from idetail where autoid not in( 
select top '+ str(@n-1) + 'autoid from idetail)' 
exec(@sql)






select top 10 * from t where id not in(select top 30 id from t order by id ) orde by id


--------------------------------------------------------------------------------


select top 10 * from t where id in (selecttop 40 id from t order by id) order by id desc




*******************************************************************************


一道面试题,写sql语句
有表a存储二叉树的节点,要用一条sql语句查出所有节点及节点所在的层.
表a 
c1 c2 A ----------1 
---- ---- / \
A B B C --------2
 A C / / \
B D D N E ------3
 C E / \ \
D F F K I ---4
E I
D K
C N




所要得到的结果如下


jd cs
----- ----
A 1
B 2
 C 2
D 3
N 3
E 3
 F 4
K 4
I 4
有高手指导一下,我只能用pl/sql写出来,请教用一条sql语句的写法


SQL> select c2, level + 1 lv
2 from test start
3 with c1 = 'A'
4 connect by c1 = prior c2
5 union
6 select 'A', 1 from dual
7 order by lv;


C2 LV
-- ----------
A 1
B 2
C 2
D 3
E 3
N 3
F 4
I 4
K 4


已选择9行。
1.一道SQL语句面试题,关于group by


表内容:


2005-05-09



2005-05-09



2005-05-09



2005-05-09



2005-05-10



2005-05-10



2005-05-10



如果要生成下列结果, 该如何写sql语句?




胜 负


2005-05-09 2 2


2005-05-10 1 2


------------------------------------------


create table #tmp(rq varchar(10),shengfunchar(1))


insert into #tmp values('2005-05-09','胜')


insert into #tmp values('2005-05-09','胜')


insert into #tmp values('2005-05-09','负')


insert into #tmp values('2005-05-09','负')


insert into #tmp values('2005-05-10','胜')


insert into #tmp values('2005-05-10','负')


insert into #tmp values('2005-05-10','负')


1)select rq, sum(case when shengfu='胜' then 1 else 0 end)'胜',sum(case when shengfu='负' then 1 else 0 end)'负' from #tmp group by rq


2) select N.rq,N.勝,M.負 from (


select rq,勝=count(*) from #tmp where shengfu='胜'group by rq)N inner join


(select rq,負=count(*) from #tmp where shengfu='负'group by rq)M on N.rq=M.rq


3)select a.col001,a.a1 胜,b.b1 负 from


(select col001,count(col001) a1 from temp1where col002='胜' group bycol001) a,


(select col001,count(col001) b1 from temp1where col002='负' group bycol001) b


where a.col001=b.col001


2.请教一个面试中遇到的SQL语句的查询问题


表中有A B C三列,用SQL语句实现:当A列大于B列时选择A列否则选择B列,当B列大于C列时选择B列否则选择C列。


------------------------------------------


select (case when a>b then a else b end),


(case when b>c then b esle c end)


from table_name


3.面试题:一个日期判断的sql语句?


请取出tb_send表中日期(SendTime字段)为当天的所有记录?(SendTime字段为datetime型,包含日期与时间)


------------------------------------------


select * from tb wheredatediff(dd,SendTime,getdate())=0


4.有一张表,里面有3个字段:语文,数学,英语。其中有3条记录分别表示语文70分,数学80分,英语58分,请用一条sql语句查询出这三条记录并按以下条件显示出来(并写出您的思路):




大于或等于80表示优秀,大于或等于60表示及格,小于60分表示不及格。




显示格式:




语文
数学
英语




及格
优秀
不及格


------------------------------------------


select


(case when 语文>=80 then '优秀'


       when 语文>=60 then'及格'


else '不及格') as 语文,


(case when 数学>=80 then '优秀'


       when 数学>=60 then'及格'


else '不及格') as 数学,


(case when 英语>=80 then '优秀'


       when 英语>=60 then'及格'


else '不及格') as 英语,


from table


5.在sqlserver2000中请用sql创建一张用户临时表和系统临时表,里面包含两个字段ID和IDValues,类型都是int型,并解释下两者的区别?


------------------------------------------


用户临时表:createtable #xx(ID int, IDValues int)


系统临时表:createtable ##xx(ID int, IDValues int)


区别:


用户临时表只对创建这个表的用户的Session可见,对其他进程是不可见的.


当创建它的进程消失时这个临时表就自动删除.


全局临时表对整个SQLServer实例都可见,但是所有访问它的Session都消失的时候,它也自动删除.


6.sqlserver2000是一种大型数据库,他的存储容量只受存储介质的限制,请问它是通过什么方式实现这种无限容量机制的。


------------------------------------------


它的所有数据都存储在数据文件中(*.dbf),所以只要文件够大,SQL    Server的存储容量是可以扩大的.


SQL Server 2000 数据库有三种类型的文件:


主要数据文件


主要数据文件是数据库的起点,指向数据库中文件的其它部分。每个数据库都有一个主要数据文件。主要数据文件的推荐文件扩展名是 .mdf。


次要数据文件


次要数据文件包含除主要数据文件外的所有数据文件。有些数据库可能没有次要数据文件,而有些数据库则有多个次要数据文件。次要数据文件的推荐文件扩展名是 .ndf。


日志文件


日志文件包含恢复数据库所需的所有日志信息。每个数据库必须至少有一个日志文件,但可以不止一个。日志文件的推荐文件扩展名是 .ldf。


7.请用一个sql语句得出结果


从table1,table2中取出如table3所列格式数据,注意提供的数据及结果不准确,只是作为一个格式向大家请教。


如使用存储过程也可以。


table1


月份mon 部门dep 业绩yj


-------------------------------


一月份     01      10


一月份     02      10


一月份     03      5


二月份     02      8


二月份     04      9


三月份     03      8


table2


部门dep     部门名称dname


--------------------------------


     01      国内业务一部


     02      国内业务二部


     03      国内业务三部


     04      国际业务部


table3 (result)


部门dep 一月份
二月份
三月份


--------------------------------------


     01      10       null      null


     02     10        8        null


     03      null      5        8


     04      null     null      9


------------------------------------------


1)


select a.部门名称dname,b.业绩yj as '一月份',c.业绩yj as '二月份',d.业绩yj as '三月份'


from table1 a,table2 b,table2 c,table2d


where a.部门dep = b.部门dep and b.月份mon = '一月份' and


a.部门dep = c.部门dep and c.月份mon = '二月份' and


a.部门dep = d.部门dep and d.月份mon = '三月份' and


2)


select a.dep,


sum(case when b.mon=1 then b.yj else 0 end)as '一月份',


sum(case when b.mon=2 then b.yj else 0 end)as '二月份',


sum(case when b.mon=3 then b.yj else 0 end)as '三月份',


sum(case when b.mon=4 then b.yj else 0 end)as '四月份',


sum(case when b.mon=5 then b.yj else 0 end)as '五月份',


sum(case when b.mon=6 then b.yj else 0 end)as '六月份',


sum(case when b.mon=7 then b.yj else 0 end)as '七月份',


sum(case when b.mon=8 then b.yj else 0 end)as '八月份',


sum(case when b.mon=9 then b.yj else 0 end)as '九月份',


sum(case when b.mon=10 then b.yj else 0end) as '十月份',


sum(case when b.mon=11 then b.yj else 0end) as '十一月份',


sum(case when b.mon=12 then b.yj else 0end) as '十二月份',


from table2 a left join table1 b on a.dep=b.dep


8.华为一道面试题


一个表中的Id有多个记录,把所有这个id的记录查出来,并显示共有多少条记录数。


------------------------------------------


select id, Count(*) from tb group by id havingcount(*)>1


select * from(select count(ID) as countfrom table group by ID)T where T.count>1




SQL面试题与答案




 1.磁盘柜上有14块73G的磁盘,
数据库为200G
大小包括日志文件,如何设置磁盘(要说明这14磁盘是怎么用的)?


  这个问题应该是考察硬件知识和数据库物理部署。


  首先需要知道这些磁盘是否要用于存放数据库备份文件和数据库性能(读/写)要求。来决定raid的级别。




1)、如果偏重于性能考虑,而且不用存放数据库备份文件的话,考虑使用raid0+1,这样可使用的磁盘容量为:14*73*50%=511G。




2)、如果读/写性能要求不高,而且还比较抠门的话,可以考虑raid5,这样可使用的磁盘容量为:13*73=949G。


  至于如何使用应该是说数据库物理文件的部署。注意说出将tempdb,data
file,log
file分开存放以减少I/O竞争即可。其实现在的条带化磁盘一般都会自动将文件分存,人为的分布已经越来越不重要了。




2.有两服务器群集,分别为node1和node2
现在要打win200系统补丁,打完后,要重新启动,如何打补丁,不能影响用户使用(要用群集的术语详细说明)。


  这个具体操作有点忘了。大致是:首先看哪个节点正在使用,通过节点IP(私有)访问另一个空闲节点,为其打上补丁,然后在群集管理器中停止该节点(也可以用命令行方式),重新启动。等到启动完毕,将切换使用节点,为另一个节点打补丁。然后重新启动。




3.有一个A
数据库,分别复制到B和C
B
要求
每次数据更新
也同时更新,C
每天更新一次就行,如何制定复制策略!


  这个应该考察的是复制知识。




a->b




1)、如果使用SQL
Server复制功能,那么让a->b使用事务性复制方式(同步复制)。




2)、如果表不多,也可以自己写触发器,利用linkserver+distribute
transaction。




a->c




1)、如果使用SQL
Server复制功能,那么让a->b使用快照复制方式,在某一时间点进行一次性复制。




2)、也可以自己写bat,将a备份后,通过ftp传输备份介质,恢复c。(比较麻烦,不推荐)




4.有一个order
表,有90个字段,20个索引,15个复合索引,其中有3个索引字段超过10个,如何进行优化


  这个问题问的比较没水平。你不详细说明这个表的使用方式(读写类的,还是几乎是静态表),就问人家怎么优化?!!还不如问问索引的分布访问原理更好。


  看得出他就想让你说:那三个索引超过10个,B树遍例效率很低,适当减少字段数目。如果是SQL2005,可以将选择性不好的字段放在“索引附加字段”中,以保证索引覆盖。而且SQL
Server由于有锁升级的毛病,可以考虑拆开表。




5.有一个数据库200G大小,每天增加50M
允许用户随时访问,制定备份策略(详细说明)。


  这种情况可以采用增量备份方式。每周日做一次全备份,周一到周六作增量备份(由于数据量较少,可以考虑每30分钟增量备份一次)。这样可以尽量减少性能消耗,而且如果transaction
log丢失的情况下,可以保证最多丢失30分钟数据。




6.管理50台数据库,日常工作是检查数据库作业是否完成,你该如何完成这项检查工作?


  这个比较简单。在每台机器上建立linkserver,然后在DBA管理服务器上做个分布式视图,每次查询该视图,各个机器上的作业情况一目了然。分布式视图写法:




create
view
vw_job




as




select
'机器一'
as
MName,*
from
linkserver1..sysjobactivity




union
all




select
'机器二'
as
MName,*
from
linkserver2..sysjobactivity




union
all




select
'机器三'
as
MName,*
from
linkserver3..sysjobactivity




7.自定义函数和存储过程的区别是什么,什么情况下只能用自定义函数,什么情况下只能用存储过程


  这个应该是考察存储过程编写经验。一般自定义函数主要用于其他sql中的调用,如:




select
yourfunc(...)
from
table


  这种情况下,一般只能通过函数实现。


  存储过程的功能要远远强于函数,例如动态执行sql(sp_executesql)的使用和一些特殊的功能,自定义函数中是不支持的,只能用存储过程实现。




8.SQL
2005
的新特性是什么

与oracle
有什么区别?




SQL
2005
的新特性一般都是和Oracle学的。


  下面是当时被leimin**着写的,你可以做个参考:


  一、数据库设计方面




1、字段类型。




varchar(max)\nvarchar(max)类型的引入大大的提高了编程的效率,可以使用字符串函数对CLOB类型进行操作,这是一个亮点。但是这就引发了对varchar和char效率讨论的老问题。到底如何分配varchar的数据,是否会出现大规模的碎片?是否碎片会引发效率问题?这都是需要进一步探讨的东西。




varbinary(max)代替image也让SQL
Server的字段类型更加简洁统一。




XML字段类型更好的解决了XML数据的操作。XQuery确实不错,但是个人对其没好感。(CSDN的开发者应该是相当的熟了!)




2、外键的级联更能扩展


  可能大部分的同行在设计OLTP系统的时候都不愿意建立外键,都是通过程序来控制父子数据的完整性。但是再开发调试阶段和OLAP环境中,外键是可以建立的。新版本中加入了SET
NULL

SET
DEFAULT
属性,能够提供能好的级联设置。




3、索引附加字段


  这是一个不错的新特性。虽然索引的附加字段没有索引键值效率高,但是相对映射到数据表中效率还是提高了很多。我做过试验,在我的实验环境中会比映射到表中提高30%左右的效率。




4、计算字段的持久化


  原来的计算字段其实和虚拟字段很像。只是管理方面好了而已,性能方面提高不多。但是SQL2005提供了计算字段的持久化,这就提高了查询的性能,但是会加重insert和update的负担。OLTP慎用。OLAP可以大规模使用。




5、分区表


  分区表是个亮点!从分区表也能看出微软要做大作强SQL
Server的信心。资料很多,这里不详细说。但是重点了解的是:现在的SQL
Server2005的表,都是默认为分区表的。因为它要支持滑动窗口的这个特性。这种特性对历史数据和实时数据的处理是很有帮助的。


  但是需要注意的一点,也是我使用过程中发现的一个问题。在建立function->schema->table后,如果在现有的分区表上建立没有显式声明的聚集索引时,分区表会自动变为非分区表。这一点很让我纳闷。如果你觉得我的非分区索引无法对起子分区,


  你可以提醒我一下呀!没有任何的提醒,直接就变成了非分区表。不知道这算不算一个bug。大家也可以试试。


  分区表效率问题肯定是大家关心的问题。在我的试验中,如果按照分区字段进行的查询(过滤)效率会高于未分区表的相同语句。但是如果按照非分区字段进行查询,效率会低于未分区表的相同语句。但是随着数据量的增大,这种成本差距会逐渐减小,趋于相等。(500万数量级只相差10%左右)




6、CLR类型


  微软对CLR作了大篇幅的宣传,这是因为数据库产品终于融入.net体系中。最开始我们也是狂喜,感觉对象数据库的一些概念可以实现了。但是作了些试验,发现使用CLR的存储过程或函数在达到一定的阀值的时候,系统性能会呈指数级下滑!这是非常危险的!只使用几个可能没有问题,当一旦大规模使用会造成严重的系统性能问题!


  其实可以做一下类比,Oracle等数据库产品老早就支持了java编程,而且提供了java池参数作为用户配置接口。但是现在有哪些系统大批使用了java存储过程?!连Oracle自己的应用都不用为什么?!还不是性能有问题!否则面向对象的数据库早就实现了!


  建议使用CLR的地方一般是和应用的复杂程度或操作系统环境有很高的耦合度的场景。如你想构建复杂的算法,并且用到了大量的指针和高级数据模型。或者是要和操作系统进行Socket通讯的场景。否则建议慎重!




7、索引视图


  索引视图2k就有。但是2005对其效率作了一些改进但是schema.viewname的作用域真是太限制了它的应用面。还有一大堆的环境参数和种种限制都让人对它有点却步。




8、语句和事务快照


  语句级快照和事务级快照终于为SQL
Server的并发性能带来了突破。个人感觉语句级快照大家应该应用。事务级快照,如果是高并发系统还要慎用。如果一个用户总是被提示修改不成功要求重试时,会杀人的!




9、数据库快照


  原理很简单,对要求长时间计算某一时间点的报表生成和防用户操作错误很有帮助。但是比起Oracle10g的闪回技术还是细粒度不够。可惜!




10、Mirror




Mirror可以算是SQL
Server的Data
guard了。但是能不能被大伙用起来就不知道了。


  二、开发方面




1、Ranking函数集


  其中最有名的应该是row_number了。这个终于解决了用临时表生成序列号的历史,而且SQL
Server2005的row_number比Oracle的更先进。因为它把Order
by集成到了一起,不用像Oracle那样还要用子查询进行封装。但是大家注意一点。如下面的例子:




select
ROW_NUMBER()
OVER
(order
by
aa)




from
tbl




order
by
bb


  会先执行aa的排序,然后再进行bb的排序。


  可能有的朋友会抱怨集成的order
by,其实如果使用ranking函数,Order
by是少不了的。如果担心Order
by会影响效率,可以为order
by的字段建立聚集索引,查询计划会忽略order
by
操作(因为本来就是排序的嘛)。




2、top


  可以动态传入参数,省却了动态SQL的拼写。




3、Apply


  对递归类的树遍历很有帮助。




4、CTE


  个人感觉这个真是太棒了!阅读清晰,非常有**感。




5、try/catch


  代替了原来VB式的错误判断。比Oracle高级不少。




6、pivot/unpivot


  个人感觉没有case直观。而且默认的第三字段(还可能更多)作为group
by字段很容易造成新手的错误。


  三、DBA管理方面




1、数据库级触发器


  记得在最开始使用2k的时候就要用到这个功能,可惜2k没有,现在有了作解决方案的朋友会很高兴吧。




2、多加的系统视图和实时系统信息


  这些东西对DBA挑优非常有帮助,但是感觉粒度还是不太细。




3、优化器的改进


  一直以来个人感觉SQL
Server的优化器要比Oracle的聪明。SQL2005的更是比2k聪明了不少。(有次作试验发现有的语句在200万级时还比50万级的相同语句要快show_text的一些提示没有找到解释。一直在奇怪。)


  论坛例子:




http://community.csdn.net/Expert/topic/4543/4543718.xml?temp=.405987








4、profiler的新事件观察


  这一点很好的加强了profiler的功能。但是提到profiler提醒大家注意一点。windows2003要安装sp1补丁才能启动profiler。否则点击没有反应。




5、sqlcmd


  习惯敲命令行的朋友可能会爽一些。但是功能有限。适合机器跑不动SQL
Server
Management
Studio的朋友使用。


  四、遗憾




1、登陆的控制


  始终遗憾SQL
Server的登陆无法分配CPU/内存占用等指标数。如果你的SQL
Server给别人分配了一个只可以读几个表的权限,而这个家伙疯狂的死循环进行连接查询,会给你的系统带来很大的负担。而SQL
Server如果能像Oracle一样可以为登陆分配如:5%的cpu,10%的内存。就可以解决这个漏洞。




2、数据库物理框架没有变动




undo和redo都放在数据库得transaction中,个人感觉是个败笔。如果说我们在设计数据库的时候考虑分多个数据库,可能能在一定程度上避免I/O效率问题。但是同样会为索引视图等应用带来麻烦。看看行级和事务级的快照数据放在tempdb中,就能感觉到目前架构的尴尬。




3、还是没有逻辑备份


  备份方面可能还是一个老大难的问题。不能单独备份几个表总是感觉不爽。灵活备份的问题不知道什么时候才能解决。




4、SSIS(DTS)太复杂了




SQL
Server的异构移植功能个人感觉最好了。(如果对比过SQL
Server的链接服务器和Oracle的透明网关的朋友会发现SQL
Server的sp_addlinkedserver(openquery)异构数据库系列比Oracle真是强太多了。)


  以前的DTS轻盈简单。但是现在的SSIS虽然功能强大了很多,但是总是让人感觉太麻烦。看看论坛中询问SSIS的贴子就知道。做的功能太强大了,往往会有很多用户不会用了。


  与oracle
有什么区别?


  这个问题相当变态!不同点我能给他讲一天!首先名字就不一样嘛!!
:)




9.DBA
的品质应该有哪些,你有哪些,
有什么欠缺的?




10。如果想配置SQL
Mail
应该在服务器安装哪些软件!


  需要哪些软件?安个outlook
express就可以了。sql
server提供接口存储过程,非常简单。


  ----------------------------


  首先从数据库设计人员角度来看:




1、SQL
Server2005之前是不支持分区表的,所以要在设计系统时考虑今后数据量大以后的数据转移问题。




2、对于树表设计来说,SQL
Server由于没有start
with
...
connect
by这样的查询方式,最好在设计表时除了ID、ParentID外,再加入TreePath字段,以避免递归循环。




3、由于SQL
Server有锁升级的毛病,频繁DML的表最好减少字段数量,以减少锁升级带来的阻塞!




4、在设计数据库物理分布的时侯,由于SQL
Server每个数据库都有自己的Transaction
Log(其中包含Undo和Redo信息),为了减轻Transaction
Log的I/O争用,可以考虑多数据库(使用聚集索引视图Clustered
View的除外)。而Oracle是数据库和实例一一对应的(RAC除外),多个表空间使用公用Undo
segement和redo
file。




5、SQL
Server的索引只有cluster
index和nocluster
index,而Oracle有Btree
index\bitmap
index\function
index等。




6、SQL
Server的最基本存储结构是页(8K),而Oracle最基本的是block可以根据OLTP和DSS的应用不同(后者可以选择大一点,利于查找效率),选择2K-32K不同block大小。




7、SQL
Server的结构是实例->多个数据库->表、存储过程...。Oracle的是数据库=实例(RAC是多个实例对应一个数据库存储)->schema(用户)表空间
->表、存储过程...。


    先写这些。。。


    -----------------------------




1.磁盘柜上有14块73G的磁盘,
数据库为200G
大小包括日志文件,如何设置磁盘(要说明这14磁盘是怎么用的)?


  答:可以做成






a.
磁盘比较充裕,做RAID10
,就是14块硬盘分一半,2个7块做Raid0,容量:7*73G=511G,然后把它们组成Raid1,最后容量(14/2)*73G=511G.
RAID10
优点,数据一次需要写入两个区块,读的时候可以从任意一个比较快的地方读取,效率很高,缺点成本较高。






b.Raid5,
13块硬盘做Raid5,1块做热冗余;
容量:
(14-2)*73G=876G,
Raid5优点,稳定系数高,性价比高。






c.Raid51,7块硬盘做Raid5,另7块也做Raid5,再把这2个Raid5做成Raid1,容量:
(14/2-1)*73G=438G,优点:比RAID10更稳定,效率和RAID10相当.




2.有两服务器群集,分别为node1和node2
现在要打win200系统补丁,打完后,要重新启动,如何打补丁,不能影响用户使用(要用群集的术语详细说明)。


  答:






a.假设node1联机并控制资源,那么先给node2
先打补丁,重起node2,这时联机并控制资源情况不会改变,不影响客户服务.






b.等node2

重起补丁完毕,手工把node1的服务和资源切换到node2,使node2处于联机状态,然后给node1打补丁,重起补丁完毕,再把node2的服务和资源切换后node1正常运作.

更多数据库知识: http://www.52mvc.com/showtopic-902.aspx

作者:jhl52771 发表于2012-11-3 20:24:55 原文链接
阅读:29 评论:0 查看评论

相关 [sql 常见 面试] 推荐:

我的Sql常见面试题(总结)

- - CSDN博客推荐文章
我开的  DBA群:225982985. 1.用一条SQL语句 查询出每门课都大于80分的学生姓名. 姓名 课程编号课程名称 分数. 1        2005001  张三 0001      数学    69. 2        2005002  李四 0001      数学    89. 3        2005001  张三 0001      数学    69.

常见 SQL 面试题:经典 50 例

- - SegmentFault 最新的文章
-- 含义是跳过2条取出1条数据,limit后面是从第2条开始读,读取1条信息,即读取第3条数据 select * from table limit 2 offset 1;. -- 含义是从第1条(不包括)数据开始取出2条数据,limit后面跟的是2条数据,offset后面是从第1条开始读取,即读取第2,3条.

SQL Server 面试

- - SQL - 编程语言 - ITeye博客
在SQL语言中,一个SELECT…FROM…WHERE语句称为一个查询块,将一个查询块嵌套在另一个查询块的WHERE子句中的查询称为子查询. 子查询分为嵌套子查询和相关子查询两种. 嵌套子查询的求解方法是由里向外处理,即每个子查询在其上一级查询处理之前求解,子查询的结果作为其父查询的查询条件. 子查询只执行一次,且可以单独执行;.

SQL常见的可优化点

- - OurMySQL
查询(或更新,删除,可以转换为查询)没有用到索引.    这是最基础的步骤,需要对sql执行explain查看执行计划中是否用到了索引,需要重点关注type=ALL, key=NULL的字段.    B树无法解决此类问题,可以考虑搜索引擎.    但是member_id like ‘alibab%’可以用到索引.

常见SQL注入方法整理系列-初始篇

- - FreeBuf.COM | 关注黑客与极客
前面介绍了MSSQL、MYSQL以及ORACLE的一些涉及安全体系的基本知识,且当作知识的积累或者温故吧. 本篇主要介绍这三种数据库的攻击手法,力求形成一套攻击流程,当然流程是死的,在真实的攻击环境中还是需要发挥聪明才智的,所以也且当作参考笔记吧. 万事开头难,SQL注入攻击同样如此. 给定一个WEB站点URL,发现该站点SQL注入漏洞最快的方法莫过于使用扫描工具,最有效的我自认为是查看应用程序源代码.

一道SQL面试题,到底能难倒了多少人?

- - V2EX - 技术
现有employee 表,表中有 员工编号(id) 员工年龄(age) 员工工资(salary) 员工部门(deptid), 按要求用一条SQL语句完成. 1.查出每个部门高于部门平均工资的员工名单. 2、列出各个部门中工资高于本部门的平均工资的员工数和部门号,并按部门号排序. 3.求每个部门工资不小于6000的人员的平均值;.

一道经典的sql面试题不同的写法

- - CSDN博客推荐文章
用一条SQL语句   查询出每门课都大于80分的学生姓名,表( #test)如下:. select '张三', '语文', 81 union. select '张三', '数学', 75 union. select '李四', '语文', 76 union. select '李四', '数学', 90 union.

10个常见的Redis面试

- -
导读:在程序员面试过程中Redis相关的知识是常被问到的话题. 作为一名在互联网技术行业打击过成百上千名的资深技术面试官,本文作者总结了面试过程中经常问到的问题. 作者简介:钱文品(老钱),互联网分布式高并发技术十年老兵,目前任掌阅科技资深后端工程师. 熟练使用 Java、Python、Golang 等多种计算机语言,开发过游戏,制作过网站,写过消息推送系统和MySQL 中间件,实现过开源的 ORM 框架、Web 框架、RPC 框架等.

PL/SQL动态SQL(原创)

- - ITeye博客
使用动态SQL是在编写PL/SQL过程时经常使用的方法之一. 很多情况下,比如根据业务的需要,如果输入不同查询条件,则生成不同的执行SQL查询语句,对于这种情况需要使用动态SQL来完成. 再比如,对于分页的情况,对于不同的表,必定存在不同的字段,因此使用静态SQL则只能针对某几个特定的表来形成分页.

数据科学家面试常见的77个问题

- - 互联网分析
随着大数据概念的火热,数据科学家这一职位应时而出,那么成为数据科学家要满足什么条件. 或许我们可以从国外的数据科学家面试问题中得到一些参考,下面是中国统计网为大家翻译的数据科学家面试常见的77个问题. 下面是77个关于数据分析或者数据科学家招聘的时候会常会的几个问题,供各位同行参考. 1、你处理过的最大的数据量.