SQL练习题(1)
1. 查询每一年加之前年份的积累销售额。比如查询2003年的,就是将2003的销售金额加上以前的销售金额。
原始数据:
id ta_year ta_num
1 2001 500
2 2002 300
3 2003 600
查询后的数据:
ta_year 销售金额
2001 500
2002 800
2003 1400
相关SQL:
--build the table
create table testA
(
id int identity(1,1) not null primary key,
ta_year char(10) not null,
ta_num int not null
)
go
-- insert the records
insert into testA values('2001',500)
insert into testA values('2002',300)
insert into testA values('2003',600)
-- here comes the selection
select b.ta_year, sum(a.ta_num) 销售金额
from testA a, testA b -- 自身连接的技巧
where a.ta_year
2. 写一个SQL语句,取出表S中第11~20条记录(SQL Server,以自动增长的ID作为主键,ID可能不连续)[分页查询]
select top 10 *
from tb
where id not in (select top 10 id
from tb)
select top 10 *
from tb
where id > (select max(id)
from(select top 10 id
from tb) as A)
select * --或列出实际所需列名
from(select *, row_number() over(order by id) row_num
from tb)A
where row_num between 11 and 20
注意:
最后一种方法,不能写成:select *, row_number() over(order by SNO) row_num from SC where row_num between 11 and 20
3.行列转置。
假设有张学生成绩表(tba)如下:
姓名 课程 分数
张三 语文 74
张三 数学 83
张三 物理 93
李四 语文 74
李四 数学 84
李四 物理 94
查询后变成:
姓名 语文 数学 物理
李四 74 84 94
张三 74 83 93
相关SQL:
-- build the table
create table tba(姓名 varchar(10),课程 varchar(10),分数 int)
go
--insert the records
insert into tba values('张三' , '语文' , 74)
insert into tba values('张三' , '数学' , 83)
insert into tba values('张三' , '物理' , 93)
insert into tba values('李四' , '语文' , 74)
insert into tba values('李四' , '数学' , 84)
insert into tba values('李四' , '物理' , 94)
go
-- here comes the selection
select 姓名,
max(case 课程 when '语文' then 分数 else 0 end) 语文,
max(case 课程 when '数学' then 分数 else 0 end) 数学,
max(case 课程 when '物理' then 分数 else 0 end) 物理
from tba
group by 姓名
4.两张表如下:
T1:
id department
1 设计
2 市场
3 售后
T2:
id depID name
1 1 张三
2 1 李四
3 2 王五
4 3 彭六
5 4 陈七
写一条sql语句,使查询结果如下:
id depID department name
1 1 设计 张三
2 1 设计 李四
3 2 市场 王五
4 3 售后 彭六
5 4 未知部门 陈七
语句如下:
select T2.id, depID, department = IsNull(department,'未知部门'), [name]
from T1 right join T2 on T1.id = T2.depID
**注:**ISNULL ( check_expression , replacement_value ),表示check_expression若为空就返回replacement_value,否则就返回check_expression。
左外连接表示左边所有信息均列出,右外同理。
5.取出分组后的前两条记录[分组后的前几项]
qu co je
A 1 3
A 2 4
A 4 2
A 6 9
B 1 4
B 2 5
B 3 6
C 3 4
C 6 7
C 2 3
查询结果应为:
qu co je
A 6 9
A 2 4
B 3 6
B 2 5
C 6 7
C 3 4
即按 qu 分组后,再取 je 最大的前两列
select qu,co,je
from hard a
where je in(select top 2 je
from hard
where qu = a.qu
order by je desc)
order by qu,je desc
select qu,co,je
from hard a
where (select count(*)
from hard
where qu = a.qu and je >= a.je) <= 2 -- n则为前n条记录
后一种比前一种效率要高
相似类型再来一例(2013-9-16加)
year product sales
2005 a 700
2005 b 550
2005 c 600
2006 a 340
2006 b 500
2007 a 220
2007 b 350
year product sales
2005 a 700
2006 b 500
2007 b 350
四种方法:
-- 方法一:
select a.year,a.product, a.sales
from @t a,(select year,max(sales) max_sales from @t group by year)b
where a.year = b.year and a.sales = b.max_sales
order by a.year
-- 方法二:
select year,product,sales from
(
select
year,product,sales,
row_number() over(partition by year order by sales desc) Rank_Num
from @t
)A
where Rank_Num = 1
-- 方法三:
select
year,product,sales
from @t a
where (select count(*) from @t where year = a.year and sales >= a.sales) <= 1 -- n則為前n項
-- 方法四:
select a.year,a.product, a.sales
from @t a
where not exists(select 1 from @t where year=a.year and sales > a.sales)
上述四种方法,效率依次升高。