最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了。
所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路。另外,考虑到前2篇太长,看起来不太方便,所以拆分为第3篇
1、分组查询问题
http://bbs.csdn.net/topics/390619682?page=1#post-395835328
例子表结构数据如下:id status date price
1 1 2013-10-01 218
2 1 2013-10-02 218
3 0 2013-10-03 218
4 0 2013-10-04 238
5 0 2013-10-05 238
6 0 2013-10-06 238
7 0 2013-10-07 258
8 0 2013-10-08 258
9 0 2013-10-09 218
想获取的结果集一:
2013-10-01至2013-10-03 218
2013-10-04至2013-10-06 238
2013-10-07至2013-10-08 258
2013-10-09至2013-10-09 218
想获取的结果集二:
1 2013-10-01至2013-10-02 218
0 2013-10-03至2013-10-03 218
0 2013-10-04至2013-10-06 238
0 2013-10-07至2013-10-08 258
0 2013-10-09至2013-10-09 218
我的解法:
--drop table tb
create table tb(id int,status int,date varchar(10),price int)
insert into tb
select 1, 1, '2013-10-01', 218 union all
select 2, 1, '2013-10-02', 218 union all
select 3, 0, '2013-10-03', 218 union all
select 4, 0, '2013-10-04', 238 union all
select 5, 0, '2013-10-05', 238 union all
select 6, 0, '2013-10-06', 238 union all
select 7, 0, '2013-10-07', 258 union all
select 8, 0, '2013-10-08', 258 union all
select 9, 0, '2013-10-09', 218 --union all
--select 10, 0, '2013-10-10', 218
go
--第一个结果集
;with t
as
(
select *,
row_number() over(partition by price order by id) as rownum,
min(id) over(partition by price) as min_id
from tb
),
tt
as
(
select id,
price,
a.date,
rownum - (id - min_id) as interval
from t a
)
select min(date) + '至' + max(date) as date,
price
from tt
group by price,interval
order by 1
/*
date price
2013-10-01至2013-10-03 218
2013-10-04至2013-10-06 238
2013-10-07至2013-10-08 258
2013-10-09至2013-10-09 218
*/
--第2个结果集
;with t
as
(
select *,
row_number() over(partition by status,price order by id) as rownum,
min(id) over(partition by status,price) as min_id
from tb
),
tt
as
(
select id,
price,
a.date,
a.status,
rownum - (id - min_id) as interval
from t a
)
select status,min(date) + '至' + max(date),price
from tt
group by status,price,interval
order by 2
/*
status date price
1 2013-10-01至2013-10-02 218
0 2013-10-03至2013-10-03 218
0 2013-10-04至2013-10-06 238
0 2013-10-07至2013-10-08 258
0 2013-10-09至2013-10-09 218
*/
2、查询出一段数据后判断记录里面的最大id,是否大于值a 查询语句如下:
http://bbs.csdn.net/topics/390619191
select top 200 id, ClassId,Name,Price,BoxContain,BoxLength,BoxWidth,BoxHeight,CName,EName,CPack,PhotoFolder,EPack,0.46*(round(((convert(decimal(10,2),BoxLength)*convert(decimal(10,2),BoxWidth) * convert(decimal(10,2),BoxHeight))/1000000),3))*35.32/BoxContain+Price/6*1.08 from ProductData where ClassId=101 and BoxContain >0 and BoxContain is not null and round(((convert(decimal(10,2),BoxLength)*convert(decimal(10,2),BoxWidth) * convert(decimal(10,2),BoxHeight))/1000000),3) >=0 And round(((convert(decimal(10,2),BoxLength)*convert(decimal(10,2),BoxWidth) * convert(decimal(10,2),BoxHeight))/1000000),3) <= 10000 and (0.46*(round(((convert(decimal(10,2),BoxLength)*convert(decimal(10,2),BoxWidth) * convert(decimal(10,2),BoxHeight))/1000000),3))*35.32/BoxContain+Price/6*1.08) >=10 and (0.46*(round(((convert(decimal(10,2),BoxLength)*convert(decimal(10,2),BoxWidth) * convert(decimal(10,2),BoxHeight))/1000000),3))*35.32/BoxContain+Price/6*1.08) <=1000 and EPack='Window Box' order by id asc
我的解法,适用于SQL Server 2000:
select *
from
(
select top 200 id, ClassId,Name,Price,BoxContain,BoxLength,BoxWidth,BoxHeight,CName,EName,CPack,PhotoFolder,EPack,
0.46*(round(((convert(decimal(10,2),BoxLength)*convert(decimal(10,2),BoxWidth) * convert(decimal(10,2),BoxHeight))/1000000),3))*35.32/BoxContain+Price/6*1.08
from ProductData
where ClassId=101 and BoxContain >0 and BoxContain is not null
and round(((convert(decimal(10,2),BoxLength)*convert(decimal(10,2),BoxWidth) * convert(decimal(10,2),BoxHeight))/1000000),3) >=0
And round(((convert(decimal(10,2),BoxLength)*convert(decimal(10,2),BoxWidth) * convert(decimal(10,2),BoxHeight))/1000000),3) <= 10000
and (0.46*(round(((convert(decimal(10,2),BoxLength)*convert(decimal(10,2),BoxWidth) * convert(decimal(10,2),BoxHeight))/1000000),3))*35.32/BoxContain+Price/6*1.08) >=10
and (0.46*(round(((convert(decimal(10,2),BoxLength)*convert(decimal(10,2),BoxWidth) * convert(decimal(10,2),BoxHeight))/1000000),3))*35.32/BoxContain+Price/6*1.08) <=1000
and EPack='Window Box'
order by id asc
)t
where
(
select max(id)
from
(
select top 200 id, ClassId,Name,Price,BoxContain,BoxLength,BoxWidth,BoxHeight,CName,EName,CPack,PhotoFolder,EPack,
0.46*(round(((convert(decimal(10,2),BoxLength)*convert(decimal(10,2),BoxWidth) * convert(decimal(10,2),BoxHeight))/1000000),3))*35.32/BoxContain+Price/6*1.08
from ProductData
where ClassId=101 and BoxContain >0 and BoxContain is not null
and round(((convert(decimal(10,2),BoxLength)*convert(decimal(10,2),BoxWidth) * convert(decimal(10,2),BoxHeight))/1000000),3) >=0
And round(((convert(decimal(10,2),BoxLength)*convert(decimal(10,2),BoxWidth) * convert(decimal(10,2),BoxHeight))/1000000),3) <= 10000
and (0.46*(round(((convert(decimal(10,2),BoxLength)*convert(decimal(10,2),BoxWidth) * convert(decimal(10,2),BoxHeight))/1000000),3))*35.32/BoxContain+Price/6*1.08) >=10
and (0.46*(round(((convert(decimal(10,2),BoxLength)*convert(decimal(10,2),BoxWidth) * convert(decimal(10,2),BoxHeight))/1000000),3))*35.32/BoxContain+Price/6*1.08) <=1000
and EPack='Window Box'
order by id asc
)t
) > a