在论坛中出现的比较难的sql问题:3(row_number函数1)
2013-10-21 10:03
330 查看
最近,在论坛中,遇到了不少比较难的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
我的解法:
2、MS-SQL 根据实际所需规格table去比对另一个库存table取浪费最少的数据 http://bbs.csdn.net/topics/390619048
情境描述:根据表A里的物料去比对表B,然后表A根据A1括号里两个尺寸浪费最少来将A1替换成最省的物料。
表A用量需求表:Table A
A0(自增长ID) A1(物料编号)
-------------------------------
0 ls001-(900*110)
1 ls002-(200*300)
....
表B库存物料表: B1没有重复,可以当作ID来使用 Table B:
B1(库存物料) B2(规格1) B3(规格2)
----------------------------------------------
ls001-(700*200) 700 200
ls001-(910*140) 910 140
ls001-(920*120) 920 120
... ... ...
ls002-(100*200) 100 200
ls002-(200*350) 200 350
ls002-(220*320) 220 320
...
原理是:ls001取(920*120)的话浪费分别是左边920-900=20,右边120-110=10,总共浪费是30, 是ls001库存规格(700*200),(910*140),(920*120)里浪费最少的,ls002同理。
最后A1字段被替换后的效果如下:
A0(自增长ID) A1(物料编号)
-------------------------------
0 ls001-(920*120)
1 ls002-(220*320)
...
各位有什么好的方案或者算法可分享来学习借鉴一下 ^_^
我的解法:
3、查询出一段数据后判断记录里面的最大id,是否大于值a 查询语句如下: http://bbs.csdn.net/topics/390619191
我的解法,适用于SQL Server 2000:
本文出自 “探索SQLServer” 博客,请务必保留此出处http://yupeigu.blog.51cto.com/3323001/1367969
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、MS-SQL 根据实际所需规格table去比对另一个库存table取浪费最少的数据 http://bbs.csdn.net/topics/390619048
情境描述:根据表A里的物料去比对表B,然后表A根据A1括号里两个尺寸浪费最少来将A1替换成最省的物料。
表A用量需求表:Table A
A0(自增长ID) A1(物料编号)
-------------------------------
0 ls001-(900*110)
1 ls002-(200*300)
....
表B库存物料表: B1没有重复,可以当作ID来使用 Table B:
B1(库存物料) B2(规格1) B3(规格2)
----------------------------------------------
ls001-(700*200) 700 200
ls001-(910*140) 910 140
ls001-(920*120) 920 120
... ... ...
ls002-(100*200) 100 200
ls002-(200*350) 200 350
ls002-(220*320) 220 320
...
原理是:ls001取(920*120)的话浪费分别是左边920-900=20,右边120-110=10,总共浪费是30, 是ls001库存规格(700*200),(910*140),(920*120)里浪费最少的,ls002同理。
最后A1字段被替换后的效果如下:
A0(自增长ID) A1(物料编号)
-------------------------------
0 ls001-(920*120)
1 ls002-(220*320)
...
各位有什么好的方案或者算法可分享来学习借鉴一下 ^_^
我的解法:
drop table a drop table b create table a (a0 int,a1 varchar(100),a2 int,a3 int) insert into a SELECT 0,'ls001-(900*110)',900,110 UNION ALL SELECT 1,'ls002-(200*300)',200,300 create table b (B1 varchar(100),B2 int,B3 int) insert into b SELECT 'ls001-(700*200)',700,200 UNION ALL SELECT 'ls001-(910*140)',910,140 UNION ALL SELECT 'ls001-(920*120)',920,120 UNION ALL SELECT 'ls002-(100*200)',100,200 UNION ALL SELECT 'ls002-(200*350)',200,350 UNION ALL SELECT 'ls002-(220*320)',220,320 ;with t as ( select a0,a1, substring(a1,1,charindex('-',a1)-1) as b1, a2,a3 --substring(a1,charindex('(',a1)+1, charindex('*',a1)-charindex('(',a1)-1) as b2, --substring(a1,charindex('*',a1)+1, charindex(')',a1)-charindex('*',a1)-1) as b3 from a ), tt as ( select t.a0, t.a1, b.b1, row_number() over(partition by t.a1 order by abs(t.a2-b.b2) + abs(t.a3 - b.b3)) as rownum from b inner join t on b.b1 like t.b1 + '%' ) select a0,b1 as a1 from tt where rownum = 1 /* a0 a1 0 ls001-(920*120) 1 ls002-(220*320) */
3、查询出一段数据后判断记录里面的最大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
本文出自 “探索SQLServer” 博客,请务必保留此出处http://yupeigu.blog.51cto.com/3323001/1367969
相关文章推荐
- 在论坛中出现的比较难的sql问题:4(row_number函数+子查询 分组连续编号问题)
- 在论坛中出现的比较难的sql问题:5(row_number函数 分页、随机返回数据)
- 在论坛中出现的比较难的sql问题:30(row_number函数 物料组合问题)
- 在论坛中出现的比较难的sql问题:2(row_number函数+子查询)
- 在论坛中出现的比较难的sql问题:2(row_number函数+子查询)
- 在论坛中出现的比较难的sql问题:31(row_number函数+子查询 月环比计算)
- 在论坛中出现的比较难的sql问题:3(row_number函数 分组查询)
- 在论坛中出现的比较难的sql问题:32(row_number函数+子查询 sql循环取差值)
- 在论坛中出现的比较难的sql问题:19(row_number函数3)
- 在论坛中出现的比较难的sql问题:19(row_number函数 行转列、sql语句记流水)
- 在论坛中出现的比较难的sql问题:29(row_number函数 组内某列的值连续出现3次标记出来)
- 在论坛中出现的比较难的sql问题:4(row_number函数+子查询2)
- 在论坛中出现的比较难的sql问题:5(row_number函数2)
- 在论坛中出现的比较难的sql问题:14(存储过程问题)
- 在论坛中出现的比较难的sql问题:25(字符串拆分3)
- 在论坛中出现的比较难的sql问题:14(存储过程问题 存储过程参数、存储过程内的参数)
- 在论坛中出现的比较难的sql问题:10(杂项问题)
- 在论坛中出现的比较难的sql问题:25(字符串拆分3)
- 在论坛中出现的比较难的sql问题:41(循环替换 循环替换关键字)
- 在论坛中出现的比较难的sql问题:22(触发器专题3)