统计排行社区应用银行社区服务会员列表最新帖子精华区搜索帮助
主题 : 按某一字段分组取最大(小)值所在行的数据
练习离线
级别: 风云使者
显示用户信息 
0 发表于: 2008-11-11  

按某一字段分组取最大(小)值所在行的数据

复制代码
  1. (爱新觉罗.毓华 2007-10-23于浙江杭州)
  2. /*
  3. 数据如下:
  4. name val memo
  5. a    2   a2(a的第二个值)
  6. a    1   a1--a的第一个值
  7. a    3   a3:a的第三个值
  8. b    1   b1--b的第一个值
  9. b    3   b3:b的第三个值
  10. b    2   b2b2b2b2
  11. b    4   b4b4
  12. b    5   b5b5b5b5b5
  13. */
  14. --创建表并插入数据:
  15. create table tb(name varchar(10),val int,memo varchar(20))
  16. insert into tb values('a',    2,   'a2(a的第二个值)')
  17. insert into tb values('a',    1,   'a1--a的第一个值')
  18. insert into tb values('a',    3,   'a3:a的第三个值')
  19. insert into tb values('b',    1,   'b1--b的第一个值')
  20. insert into tb values('b',    3,   'b3:b的第三个值')
  21. insert into tb values('b',    2,   'b2b2b2b2')
  22. insert into tb values('b',    4,   'b4b4')
  23. insert into tb values('b',    5,   'b5b5b5b5b5')
  24. go
  25. --一、按name分组取val最大的值所在行的数据。
  26. --方法1:
  27. select a.* from tb a where val = (select max(val) from tb where name = a.name) order by a.name
  28. --方法2:
  29. select a.* from tb a where not exists(select 1 from tb where name = a.name and val > a.val)
  30. --方法3:
  31. select a.* from tb a,(select name,max(val) val from tb group by name) b where a.name = b.name and a.val = b.val order by a.name
  32. --方法4:
  33. select a.* from tb a inner join (select name , max(val) val from tb group by name) b on a.name = b.name and a.val = b.val order by a.name
  34. --方法5
  35. select a.* from tb a where 1 > (select count(*) from tb where name = a.name and val > a.val ) order by a.name
  36. /*
  37. name       val         memo                
  38. ---------- ----------- --------------------
  39. a          3           a3:a的第三个值
  40. b          5           b5b5b5b5b5
  41. */
  42. --二、按name分组取val最小的值所在行的数据。
  43. --方法1:
  44. select a.* from tb a where val = (select min(val) from tb where name = a.name) order by a.name
  45. --方法2:
  46. select a.* from tb a where not exists(select 1 from tb where name = a.name and val < a.val)
  47. --方法3:
  48. select a.* from tb a,(select name,min(val) val from tb group by name) b where a.name = b.name and a.val = b.val order by a.name
  49. --方法4:
  50. select a.* from tb a inner join (select name , min(val) val from tb group by name) b on a.name = b.name and a.val = b.val order by a.name
  51. --方法5
  52. select a.* from tb a where 1 > (select count(*) from tb where name = a.name and val < a.val) order by a.name
  53. /*
  54. name       val         memo                
  55. ---------- ----------- --------------------
  56. a          1           a1--a的第一个值
  57. b          1           b1--b的第一个值
  58. */
  59. --三、按name分组取第一次出现的行所在的数据。
  60. select a.* from tb a where val = (select top 1 val from tb where name = a.name) order by a.name
  61. /*
  62. name       val         memo                
  63. ---------- ----------- --------------------
  64. a          2           a2(a的第二个值)
  65. b          1           b1--b的第一个值
  66. */
  67. --四、按name分组随机取一条数据。
  68. select a.* from tb a where val = (select top 1 val from tb where name = a.name order by newid()) order by a.name
  69. /*
  70. name       val         memo                
  71. ---------- ----------- --------------------
  72. a          1           a1--a的第一个值
  73. b          5           b5b5b5b5b5
  74. */
  75. --五、按name分组取最小的两个(N个)val
  76. select a.* from tb a where 2 > (select count(*) from tb where name = a.name and val < a.val ) order by a.name,a.val
  77. select a.* from tb a where val in (select top 2 val from tb where name=a.name order by val) order by a.name,a.val
  78. select a.* from tb a where exists (select count(*) from tb where name = a.name and val < a.val having Count(*) < 2) order by a.name
  79. /*
  80. name       val         memo                
  81. ---------- ----------- --------------------
  82. a          1           a1--a的第一个值
  83. a          2           a2(a的第二个值)
  84. b          1           b1--b的第一个值
  85. b          2           b2b2b2b2
  86. */
  87. --六、按name分组取最大的两个(N个)val
  88. select a.* from tb a where 2 > (select count(*) from tb where name = a.name and val > a.val ) order by a.name,a.val
  89. select a.* from tb a where val in (select top 2 val from tb where name=a.name order by val desc) order by a.name,a.val
  90. select a.* from tb a where exists (select count(*) from tb where name = a.name and val > a.val having Count(*) < 2) order by a.name
  91. /*
  92. name       val         memo                
  93. ---------- ----------- --------------------
  94. a          2           a2(a的第二个值)
  95. a          3           a3:a的第三个值
  96. b          4           b4b4
  97. b          5           b5b5b5b5b5
  98. */
  99. --七,如果整行数据有重复,所有的列都相同。
  100. /*
  101. 数据如下:
  102. name val memo
  103. a    2   a2(a的第二个值)
  104. a    1   a1--a的第一个值
  105. a    1   a1--a的第一个值
  106. a    3   a3:a的第三个值
  107. a    3   a3:a的第三个值
  108. b    1   b1--b的第一个值
  109. b    3   b3:b的第三个值
  110. b    2   b2b2b2b2
  111. b    4   b4b4
  112. b    5   b5b5b5b5b5
  113. */
  114. --在sql server 2000中只能用一个临时表来解决,生成一个自增列,先对val取最大或最小,然后再通过自增列来取数据。
  115. --创建表并插入数据:
  116. create table tb(name varchar(10),val int,memo varchar(20))
  117. insert into tb values('a',    2,   'a2(a的第二个值)')
  118. insert into tb values('a',    1,   'a1--a的第一个值')
  119. insert into tb values('a',    1,   'a1--a的第一个值')
  120. insert into tb values('a',    3,   'a3:a的第三个值')
  121. insert into tb values('a',    3,   'a3:a的第三个值')
  122. insert into tb values('b',    1,   'b1--b的第一个值')
  123. insert into tb values('b',    3,   'b3:b的第三个值')
  124. insert into tb values('b',    2,   'b2b2b2b2')
  125. insert into tb values('b',    4,   'b4b4')
  126. insert into tb values('b',    5,   'b5b5b5b5b5')
  127. go
  128. select * , px = identity(int,1,1) into tmp from tb
  129. select m.name,m.val,m.memo from
  130. (
  131.   select t.* from tmp t where val = (select min(val) from tmp where name = t.name)
  132. ) m where px = (select min(px) from
  133. (
  134.   select t.* from tmp t where val = (select min(val) from tmp where name = t.name)
  135. ) n where n.name = m.name)
  136. drop table tb,tmp
  137. /*
  138. name       val         memo
  139. ---------- ----------- --------------------
  140. a          1           a1--a的第一个值
  141. b          1           b1--b的第一个值
  142. (2 行受影响)
  143. */
  144. --在sql server 2005中可以使用row_number函数,不需要使用临时表。
  145. --创建表并插入数据:
  146. create table tb(name varchar(10),val int,memo varchar(20))
  147. insert into tb values('a',    2,   'a2(a的第二个值)')
  148. insert into tb values('a',    1,   'a1--a的第一个值')
  149. insert into tb values('a',    1,   'a1--a的第一个值')
  150. insert into tb values('a',    3,   'a3:a的第三个值')
  151. insert into tb values('a',    3,   'a3:a的第三个值')
  152. insert into tb values('b',    1,   'b1--b的第一个值')
  153. insert into tb values('b',    3,   'b3:b的第三个值')
  154. insert into tb values('b',    2,   'b2b2b2b2')
  155. insert into tb values('b',    4,   'b4b4')
  156. insert into tb values('b',    5,   'b5b5b5b5b5')
  157. go
  158. select m.name,m.val,m.memo from
  159. (
  160.   select * , px = row_number() over(order by name , val) from tb
  161. ) m where px = (select min(px) from
  162. (
  163.   select * , px = row_number() over(order by name , val) from tb
  164. ) n where n.name = m.name)
  165. drop table tb
  166. /*
  167. name       val         memo
  168. ---------- ----------- --------------------
  169. a          1           a1--a的第一个值
  170. b          1           b1--b的第一个值
  171. (2 行受影响)
  172. */



复制代码
  1. select a.* from ad_info a inner join (
  2. select sf_userid,max(sf_rec)as sf_rec from ad_info
  3. )b on a.sf_userid=b.sf_userid and a.sf_rec=b.sf_rec
  4. order by sf_rec desc,id desc
描述
快速回复

按"Ctrl+Enter"直接提交
上一个下一个