MS SQL SERVER培训用问题集锦

编者:NCFIRE

开门见山 

--------------------------------------------------------------------------------------------------
问题1、关于子查询

假设有个表内的内容如下:
A       B       C
————————————
0001    1       A002
0001    1       A005
0001    2       A005
0002    5       A008
0003    3       B001
0003    1       B009
要得到的结果是
A       B       C
————————————
0001    1       A005
0002    5       A008
0003    1       B009
按照A进行分组,选择B最小的记录,如果有B相等的记录,选择C最大的记录

-------------------------------------
可以达到目的的解答

declare @t table(a varchar(4),b int , c varchar(4))
insert into @t
select '0001', 1, 'A002' union
select '0001', 1, 'A005' union
select '0001', 2, 'A005' union
select '0002', 5, 'A008' union
select '0003', 3, 'B001' union
select '0003', 1, 'B009'

 

select t1.a,t1.b , max(t2.c) as c
from
(
select a,
       min(b) as b
from    @t
group by a
)  t1
inner join @t t2 on t1.a = t2.a
group by t1.a,t1.b
--------------------------------
推荐解答:

declare @t table(a varchar(4),b int , c varchar(4))
insert into @t
select '0001', 1, 'A002' union
select '0001', 1, 'A005' union
select '0001', 2, 'A005' union
select '0002', 5, 'A008' union
select '0003', 3, 'B001' union
select '0003', 1, 'B009'


SELECT *
from @t as t
where t.b<= all
(
 select b
 from @t as t1
 where t.a=t1.a
)
and t.c>= all
(
 select c
 from @t as t2
 where t.a=t2.a
)
---------------------------------------------------------------------------------------------------------------------------------

问题2 关于联合查询

问题:(从多个表里取出数据,组合成一个临时表)怎么写呀!!!!

解答:
SELECT * INTO #TMP
FROM
(
[SELECT。。]
UNION ALL --注意加与不加ALL的区别
[SELECT。。]
) AS T

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

问题3 关于日期函数与虚视图子查询的高级应用

问题描述:

求SQL语句:

TAB1:
ID QTY1
01    0
02  0

TAB2:
ID  DATE1     QTYDay1
01 2006-05-01 15
01 2006-06-04 16
01 2006-06-06 18
02 2006-04-03 11
02 2006-06-06 13


如何更新TAB1 QTY1.公式如下:
01 QYT1=(Datediff(dd,2006-05-01,2006-06-04) *15)+(Datediff(dd,2006-06-04,2006-06-06) *16)+(Datediff(dd,2006-06-06,当天) *18)

02 QYT1=(Datediff(dd,2006-04-03,2006-06-06) *11)+(Datediff(dd,2006-06-06,当天) *13)


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

推荐解答:

CREATE TABLE #tab1 (ID CHAR(2) , QTY1 INT )
INSERT INTO #TAB1
SELECT '01',    0
UNION ALL
SELECT '02',  0

CREATE TABLE #tab2 ( ID CHAR(2) , DATE1 DATETIME , QTYDAY1 INT)
INSERT INTO #TAB2
SELECT '01', '2006-05-01', 15
UNION ALL
SELECT '01', '2006-06-04', 16
UNION ALL
SELECT '01', '2006-06-06', 18
UNION ALL
SELECT '02', '2006-04-03', 11
UNION ALL
SELECT '02', '2006-06-06', 13


update #tab1
set #tab1.qty1 = t.qty
from
(
 select id , sum(Datediff(dd,date1,date2) *qtyday1) as qty
 from
 (
   select a.id , a.date1 , min(b.date1 ) as date2 , a.qtyday1
   from #tab2 as a
   join
   (
    select * from #tab2
    union all --注意这里
    select id , getdate() , getdate() from #tab1
   ) as b
   on a.id = b.id
   and a.date1 < b.date1
   group by a.id , a.date1 , a.qtyday1
 ) as c
 group by c.id
) as t
where #tab1.id = t.id

SELECT * FROM #TAB1


--------------------------------------------------------------------------------------------------------------------------------------
问题4 关于分组过滤与TOP的使用

求教如何选择相同数据的插入先后问题

我有一个表,
插入了数条数据,
id    name                  

10  a                  
30  b                 
0   c                  
30  d
现在我想查询id最大的行相对应的name值,但是使用max()函数得到的值是d,因为d后插入
我想的到最先插入的那一项的name值,怎么才能做到呢?

----------------------------------------------------------
解答:
declare @t table (id int , name char(1))
insert into @t
select 10,  'a' 
union                
select 30 , 'b'            
union    
select 0 , 'c'                  
union
select 30 , 'd'

select top 1 name
from @t
group by id ,name
having max(id) =id

-------------------------------------------------------------------------------------------------------------------------------------------
问题5 关于动态SQL查询

问题描述:求一存储过程,取得指定表中最大的ID号,这里的表是参数

解答:

CREATE PROCEDURE SelectMax
 @max int output,
 @Tablename varchar(50)
 AS
exec('select max(ID) as ret into t from '+@Tablename)
select @max = ret from t
drop table t
return @max
-------------------------------------------------------------------------------------------------------------------------------------------
问题 关于外联接查询

问题描述:一张是从人事得到的表,一张是从教育的到的表,两张表除了姓名是有相同的其他没什么是一样的,但教育表的人员数量又比人事的少。

现在我想做一个视图,以人事表为主,如果教育表没有相应的人名则教育相关信息为“暂无记录”!


解答:
select a.*,isnull(b.教育信息,'暂无记录')
from 人事表 as a
left join 教育表 as b
on a.部门=b.部门 and a.姓名=b.姓名
-------------------------------------------------------------------------------------------------------------------------------------------
问题 关于MSSQL中的批语句

问题描述:

有这样一个表tb1:
sail  cmd
9258  LBQR|LB
92587  A|19|1

我想得到下面的结果:
sail  cmd
9258  LBQR
9258  LB
92587  A
92587 19
92587 1

请问怎么写?


解答1(利用批语句辗转求集):
create table t(a int ,b varchar(100))
go

insert into t
values(9258 , 'LBQR|LB')
insert into t
values(92587,  'A|19|1')
go

declare @t table(a int ,b varchar(100))
select * into #t from t
while exists(select * from #t where b like '%|%')
begin
 insert into @t select * from #t where b not like '%|%'
 delete #t where b not like '%|%'
 insert into @t select a,left(b,charindex('|',b)-1 ) from #t
 update #t set b = right(b,len(b)-charindex('|',b) )
end
insert into @t select * from #t where b not like '%|%'
select * from @t
drop table #t
drop table t
------------------------------------------------------------------
解答2 (巧妙构造起始位置索引集合)
DECLARE @t TABLE(ID int, Work varchar(8000))
INSERT @t SELECT 9258, 'LBQR|LB'
UNION ALL SELECT 92587, 'A|19|1'

-- 分拆处理
SELECT TOP  100 id = IDENTITY(int,1,1) INTO #T FROM syscolumns a, syscolumns b
SELECT A.ID, Work = SUBSTRING(A.Work, B.id, CHARINDEX('|', A.Work + '|', B.id) - B.id)
FROM @t A, #T B
WHERE SUBSTRING('|' + A.Work, B.id, 1) = '|'
DROP TABLE #T

-------------------------------------------------------------------------------------------------------------------------------------------
问题8 简单的集合运算(关系减),正确使用IN

不同于ORACLE,T-SQL没有关系减运算操作符,不过可以通过转化来完成

问题描述:
table 1
id  value
1    111
1    222
1    444
3    333
3    444

table 2
id  value
1    222
1    444
2    111
3    444

得到
table 2
id  value
1    111
3    333

解答:
select * from table1
where value not in (select value from table2 where table1.id = table2.id)

-------------------------------------------------------------------------------------------------------------------------------------------
问题9 三个表关联问题,关于查询中自行构造参照完整性约束

问题描述:

有三个表 a,b,c
a表中字段
id userno issite
1  0283    1
2  0892    0
b表中字段
id userno tel fax
1  0283   028  028
c表中字段
id userno tel fax
1  0892   028  028
issite表示该会员是否为本站会员.如果是的话就从b表中读出该会员的资料.如果不是的话就从c表中读出他的资料.资料包括电话,传真.

请问从A表中如何读出0283, 0892两个会员的资料.这个SQL语句怎么写。。谢谢 了。
能不能用一句SQL解决此问题。

解答:
select *
from a
join
(
 select b.* , 1 as issite from b
 union
 select c.* , 0 from c
) as t
on a.userno = t.userno
and a.issite = t.issite
-------------------------------------------------------------------------------------------------------------------------------------------
问题10 带主外键关系的触发器怎么写,级联删除

问题描述:
tch(id,……)
tcourse(t_id,c_id,……)
  两个表,tch (id 为key)和tcourse (t_id为key),如果不定义tcourse的t_id为外键与tch的id为主键的主外键关系的话,

CREATE TRIGGER deltch1 ON [dbo].[tch]
FOR delete
AS
IF @@ROWCOUNT = 0
RETURN
delete from tcourse where t_id =  (select id from deleted)

下面的触发器可以在删除教师的信息时,把tcourse中所相关的记录删除,但在定义主外键关系后,则不行,请问该如何修改?

--------------------------------------------------------------
解答1:

不用触发器,定义外键时可以指定on cascade delete

解答2:
改成INSTEAD OF 触发器即可

CREATE TRIGGER deltch1 ON [dbo].[tch]
INSTEAD OF delete
AS
IF @@ROWCOUNT = 0
RETURN
delete from tcourse where t_id =  (select id from deleted)
delete from tch where id = (select id from deleted)

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


问题11 合理使用CASE

问题描述:

有表:A

a char(10), b int(8)
'aa',       150
'aa',       200
'bb',       100
'cc',       100

有表:B  字段a同A表中的a,
a char(10),b int(8),c char(10)
'aa',      100,      T
'aa',      200,      F
'bb',      200,      T

欲求出这样的结果:

'aa',   sum(B.b) as b1 (条件 c='T'),sum(B.b) as b2 (条件 c='F'),sum(A.b) as b3

请问这样的该如何做到?
------------------------------------------------------

select a.a,isnull(t.b1,0),isnull(t.b2,0),a.c
from a
left join
(
 select a,sum(case c when 't' then b else 0 end) as b1,sum(case c when 'f' then b else 0 end) as b2
 from b
 group by a
) as t
on a.a=t.a
--------------------------------------------------------------------------------------------------------------------------------------------------------------------

问题12 动态SQL构造问题

问题描述:
求一SQL求和问题

假如表A
id
2
3
5
假设数字B=1000,我想用B除以表A中的每一项,然后相加,结果是C=1000/2+1000/3+1000/5
好像需要用到循环,请问这个怎么实现?
--------------------------------------------
答案:
create table kk(id int )
go
insert into kk values(2)
insert into kk values(3)
insert into kk values(5)

declare @sql varchar(8000)
declare @c int
set @sql = ''
select @sql=@sql+'1000/'+cast(id as varchar(10))+'+'
from kk
set @sql = left(@sql ,len(@sql)-1)
print @sql
set @sql = 'select '+@sql+'as c into t'

exec(@sql)

select @c = c from t

print @c

drop table t

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值