在论坛中出现的比较难的sql问题:3(row_number函数 分组查询)

原文: 在论坛中出现的比较难的sql问题:3(row_number函数 分组查询)

最近,在论坛中,遇到了不少比较难的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


我的解法:


   
   
  1. --drop table tb
  2. create table tb( id int, status int, date varchar( 10),price int)
  3. insert into tb
  4. select 1, 1, '2013-10-01', 218 union all
  5. select 2, 1, '2013-10-02', 218 union all
  6. select 3, 0, '2013-10-03', 218 union all
  7. select 4, 0, '2013-10-04', 238 union all
  8. select 5, 0, '2013-10-05', 238 union all
  9. select 6, 0, '2013-10-06', 238 union all
  10. select 7, 0, '2013-10-07', 258 union all
  11. select 8, 0, '2013-10-08', 258 union all
  12. select 9, 0, '2013-10-09', 218 --union all
  13. --select 10, 0, '2013-10-10', 218
  14. go
  15. --第一个结果集
  16. ;with t
  17. as
  18. (
  19. select *,
  20. row_number() over( partition by price order by id) as rownum,
  21. min( id) over( partition by price) as min_id
  22. from tb
  23. ),
  24. tt
  25. as
  26. (
  27. select id,
  28. price,
  29. a.date,
  30. rownum - ( id - min_id) as interval
  31. from t a
  32. )
  33. select min( date) + '至' + max( date) as date,
  34. price
  35. from tt
  36. group by price, interval
  37. order by 1
  38. /*
  39. date price
  40. 2013-10-01至2013-10-03 218
  41. 2013-10-04至2013-10-06 238
  42. 2013-10-07至2013-10-08 258
  43. 2013-10-09至2013-10-09 218
  44. */
  45. --第2个结果集
  46. ;with t
  47. as
  48. (
  49. select *,
  50. row_number() over( partition by status,price order by id) as rownum,
  51. min( id) over( partition by status,price) as min_id
  52. from tb
  53. ),
  54. tt
  55. as
  56. (
  57. select id,
  58. price,
  59. a.date,
  60. a.status,
  61. rownum - ( id - min_id) as interval
  62. from t a
  63. )
  64. select status, min( date) + '至' + max( date),price
  65. from tt
  66. group by status,price, interval
  67. order by 2
  68. /*
  69. status date price
  70. 1 2013-10-01至2013-10-02 218
  71. 0 2013-10-03至2013-10-03 218
  72. 0 2013-10-04至2013-10-06 238
  73. 0 2013-10-07至2013-10-08 258
  74. 0 2013-10-09至2013-10-09 218
  75. */


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:


   
   
  1. select *
  2. from
  3. (
  4. select top 200 id, ClassId, Name,Price,BoxContain,BoxLength,BoxWidth,BoxHeight,CName,EName,CPack,PhotoFolder,EPack,
  5. 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
  6. from ProductData
  7. where ClassId= 101 and BoxContain > 0 and BoxContain is not null
  8. and round((( convert( decimal( 10, 2),BoxLength)* convert( decimal( 10, 2),BoxWidth) * convert( decimal( 10, 2),BoxHeight))/ 1000000), 3) >= 0
  9. And round((( convert( decimal( 10, 2),BoxLength)* convert( decimal( 10, 2),BoxWidth) * convert( decimal( 10, 2),BoxHeight))/ 1000000), 3) <= 10000
  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) >= 10
  11. 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
  12. and EPack= 'Window Box'
  13. order by id asc
  14. )t
  15. where
  16. (
  17. select max( id)
  18. from
  19. (
  20. select top 200 id, ClassId, Name,Price,BoxContain,BoxLength,BoxWidth,BoxHeight,CName,EName,CPack,PhotoFolder,EPack,
  21. 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
  22. from ProductData
  23. where ClassId= 101 and BoxContain > 0 and BoxContain is not null
  24. and round((( convert( decimal( 10, 2),BoxLength)* convert( decimal( 10, 2),BoxWidth) * convert( decimal( 10, 2),BoxHeight))/ 1000000), 3) >= 0
  25. And round((( convert( decimal( 10, 2),BoxLength)* convert( decimal( 10, 2),BoxWidth) * convert( decimal( 10, 2),BoxHeight))/ 1000000), 3) <= 10000
  26. 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
  27. 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
  28. and EPack= 'Window Box'
  29. order by id asc
  30. )t
  31. ) > a


发布了416 篇原创文章 · 获赞 135 · 访问量 94万+

猜你喜欢

转载自www.cnblogs.com/lonelyxmas/p/12019978.html
今日推荐