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