有这样的表,主要是两个字段,ACC_NBR和STATE,其他的字段我们不需要管:
acc_nbr state
111111 1
111111 2
111111 1
222222 1
222222 2
我最终要得到如下的结果:
111111 1
222222 1
也就是说,acc_nbr的字段的值会有重复的结果,但是每个值我只要取一条记录,使得ACC_NBR成为主键,而ACC_NBR取值的条件是state 的最小值,所以总结来说,每个acc_nbr的值我要取,且仅一条当state值为最小的值.
大家有没有什么好办法,愿听其详
但是,请不要用这种 select min(acc_nbr),min(state) from 表 这样的方法,这样肯定和我的要求不相符.
有能解决的50分奉上!
acc_nbr state
111111 1
111111 2
111111 1
222222 1
222222 2
我最终要得到如下的结果:
111111 1
222222 1
也就是说,acc_nbr的字段的值会有重复的结果,但是每个值我只要取一条记录,使得ACC_NBR成为主键,而ACC_NBR取值的条件是state 的最小值,所以总结来说,每个acc_nbr的值我要取,且仅一条当state值为最小的值.
大家有没有什么好办法,愿听其详
但是,请不要用这种 select min(acc_nbr),min(state) from 表 这样的方法,这样肯定和我的要求不相符.
有能解决的50分奉上!
from tb t
where state=(select top 1 state from tb where acc_nbr=t.acc_nbr order by newid())
(爱新觉罗.毓华 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
/*
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
/*
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')
goselect * , px = identity(int,1,1) into tmp from tbselect 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')
goselect 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 行受影响)
*/
数据如下:
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
*/--四、按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
*/
from (select distinct * from ta ) a
where exists(select 1
from (select distinct * from ta ) b
where a.acc_nbr = b.acc_nbr and a.state < b.state)
-- Author:Flystone
-- Version:V1.001
-- Date:2008-07-13 21:36:57
-------------------------------------- Test Data: ta
If object_id('ta') is not null
Drop table ta
Go
Create table ta(acc_nbr varchar(10),state int)
Go
Insert into ta
select '111111',1 union all
select '111111',2 union all
select '111111',1 union all
select '222222',1 union all
select '222222',2
Go
--Start
select *
from (select distinct * from ta ) a
where exists(select 1
from (select distinct * from ta ) b
where a.acc_nbr = b.acc_nbr and a.state < b.state)
--Result:
/*acc_nbr state
---------- -----------
111111 1
222222 1(所影响的行数为 2 行)*/
--End
where exists(select 1
from (select distinct * from ta ) b
where a.acc_nbr = b.acc_nbr and a.state < b.state)
这句是啥意思呢? 你把表让他自己和自己关联了起来?
关键是这个 select 1 from ..... 为啥要select 1 呢?
Set Nocount On
declare @1 table([acc_nbr] int,[state] int)
Insert @1
select 111111,1 union all
select 111111,2 union all
select 111111,1 union all
select 222222,1 union all
select 222222,2
Select Distinct * from @1 a Where [state]=(Select Min([state]) From @1 Where [acc_nbr]=a.[acc_nbr])
/*
acc_nbr state
----------- -----------
111111 1
222222 1*/
from # a
where exists(select 1
from # b
where a.acc_nbr = b.acc_nbr and a.state < b.state)
--这样看吧exists仅是一个存在性判断 ,所以select 1 或不是1 都无所谓啦
from (select distinct * from ta ) a
where exists(select 1
from (select distinct * from ta ) b
where a.acc_nbr = b.acc_nbr and a.state < b.state)
(select acc_nbr=111111, stat=1 union all select 111111,2
union all select 111111,1
union all select 222222,1
union all select 222222,2)xselect * from #t--2005
with cte
as
(select *,px=row_number() over(partition by acc_nbr order by stat)
from #t)
select acc_nbr, stat from cte a where exists (select acc_nbr from cte b group by acc_nbr having min(b.px)=a.px)
--2000
select top 100 percent id=identity(int,1,1),* into #t2 from #t order by acc_nbr,stat
select acc_nbr,stat from #t2 a where exists(select acc_nbr from #t2 b group by acc_nbr having min(b.id)=a.id)
这个name=a.name 我有点不懂。请大家指教下。。
acc_nbr state
111111 1
111111 2
111111 1
222222 1
222222 2
我最终要得到如下的结果:
111111 1
222222 1
-----------------------------------------------------------------
上面几楼的貌似都不行,LZ的数据有重复的,而楼主并没有给出主键。
建议:
1、如果只是取两个字段:
select acc_nbr,min(state) from tb group by acc_nbr
2、如果还要其它字段:
1)如果存在主键,比如ID
select * from tb a where id =
(select top 1 id from tb where a.acc_nbr = acc_nbr order by state)
2)如果不存在主键,则下面的语句可以,但不太可靠。
select * from tb a where checksum(*) =
(select top 1 checksum(*) from tb where a.acc_nbr = acc_nbr order by state)
create table #test_1
(
acc_nbr int,
state int
)insert into #test_1
select 111111 , 1
union
select 111111 , 2
union
select 111111 , 1
union
select 222222 , 1
union
select 222222 , 2 select max(acc_nbr) as [acc_nbr],min(state) as [state] from #test_1 group by acc_nbrdrop table #test_1(所影响的行数为 4 行)acc_nbr state
----------- -----------
111111 1
222222 1(所影响的行数为 2 行)
select * from
(
select *,num=(row_number() over (partition by acc_nbr order by acc_nbr,state))
from tb
) aa
where num=1
use test
create table csdn(acc_nbr nvarchar(20),state int)
go
insert csdn(acc_nbr,state) values('111111',1)
insert csdn(acc_nbr,state) values('111111',2)
insert csdn(acc_nbr,state) values('111111',1)
insert csdn(acc_nbr,state) values('222222',1)
insert csdn(acc_nbr,state) values('222222',1)select acc_nbr,min(state) as state from csdn group by acc_nbr
If object_id('ta') is not null
Drop table ta
Go
Create table ta(acc_nbr varchar(10),state int)
Go
Insert into ta
select '111111',1 union all
select '111111',2 union all
select '111111',1 union all
select '222222',1 union all
select '222222',2
Go
--Startselect distinct * from ta a where not exists(select 0 from ta b where a.acc_nbr=b.acc_nbr and a.state>b.state)
-----------------------------
acc_nbr state
---------- -----------
111111 1
222222 1(所影响的行数为 2 行)
from 表名
group by acc_nbr
insert into test values(111111,1)
insert into test values(111111,2)
insert into test values(111111,1)
insert into test values(222222,1)
insert into test values(222222,2)select acc_nbr,min(state)
from test
group by acc_nbr,state
having min(state)
go
create table #T(acc_nbr int, state int)
insert into #T
select 111111, 1 union all
select 111111, 2 union all
select 111111, 1 union all
select 222222, 1 union all
select 222222, 2/*
据分析,测试数据中(acc_nbr,state)不唯一,直接
select * from #T as a where not exists (select 1 from #T where acc_nbr = a.acc_nbr and state < a.state)
如果min(state)重复,会产生类似
select top 1 WITH TIES * from #T order by state
的效果,这个问题是要考虑的,除非需求如此。
下面通过临时表生成唯一标识(SQL2005或使用ROW_NUMBER函数),借助唯一标识来解决这个问题。
*/if object_id('tempdb.dbo.#RID') is not null drop table #RID
select RID = identity(int,1,1), * into #RID from #Tselect acc_nbr, state from #RID as a where not exists (select 1 from #RID where acc_nbr = a.acc_nbr and state < a.state) and not exists (select 1 from #RID where acc_nbr = a.acc_nbr and state = a.state and RID < a.RID)
/*
acc_nbr state
-------- --------
111111 1
222222 1
*/--或随机取1条:
select acc_nbr, state from #RID as a where not exists (select 1 from #RID where acc_nbr = a.acc_nbr and state < a.state) and RID = (select top 1 RID from #RID where acc_nbr = a.acc_nbr and state = a.state order by newid())
/*
acc_nbr state
-------- --------
111111 1
222222 1
*/--上面有提到用子查询 distinct * 的解决方法,怎么说呢,如果就这两个字段,一个group by就解决问题:
select acc_nbr, state = min(state) from #T group by acc_nbr
/*
acc_nbr state
-------- --------
111111 1
222222 1
*/--如果不仅仅是这两个字段,用 distinct * 恐怕不可靠。