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