---分组、排序求更好的方法---

luoyoumou 2009-10-27 01:14:21
现A表有以下数据结构: 
rq ddsj
--------------------
200805 30
200805 40
200805 50
200805 20
200806 250
200806 200
200806 310
200806 100
200806 300
200806 130
200806 430
--------------------
按rp分组、ddsj排序,选择出每组摆在正中间的记录行(若为偶数行的话,选择摆在正中间的两条记录行)
drop table a;

create table a(rq varchar(8), ddsj int)
insert into a
select
'200805',30 union all select
'200805',40 union all select
'200805',50 union all select
'200805',20 union all select
'200806',250 union all select
'200806',200 union all select
'200806',310 union all select
'200806',100 union all select
--'200806',300 union all select
'200806',130;

------我的方法如下:
select t1.orders, t1.rq, t1.ddsj
from ( select ROW_NUMBER() OVER(PARTITION BY rq ORDER BY ddsj ) orders, rq, ddsj from a ) t1
inner join ( select rq, max(orders)+2 orders from
(select rq, ROW_NUMBER() OVER(PARTITION BY rq ORDER BY ddsj ) orders from a ) t3 group by rq )
t2
on t1.rq=t2.rq and ((t1.orders=convert(int,t2.orders/2) or t1.orders=convert(int,(t2.orders-0.5)/2)));

---求更好的方法????
...全文
253 35 打赏 收藏 转发到动态 举报
写回复
用AI写文章
35 条回复
切换为时间正序
请发表友善的回复…
发表回复
chnerhu 2009-10-29
  • 打赏
  • 举报
回复
强悍!
James__Zhan 2009-10-28
  • 打赏
  • 举报
回复
学习...
taoistong 2009-10-28
  • 打赏
  • 举报
回复
人齐结帖
duanxugang 2009-10-28
  • 打赏
  • 举报
回复
学习
幸运的意外 2009-10-28
  • 打赏
  • 举报
回复
我公司用的是2000,估计实现这个问题老麻烦了吧.
luoyoumou 2009-10-27
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 devilidea 的回复:]

[/Quote]

???
devilidea 2009-10-27
  • 打赏
  • 举报
回复
小宏 2009-10-27
  • 打赏
  • 举报
回复
小麦帅了一米
dawugui 2009-10-27
  • 打赏
  • 举报
回复
--sql 2000的写法.
create table a(rq varchar(8), ddsj int)
insert into a
select
'200805',30 union all select
'200805',40 union all select
'200805',50 union all select
'200805',20 union all select
'200806',250 union all select
'200806',200 union all select
'200806',310 union all select
'200806',100 union all select
--'200806',300 union all select
'200806',130;

select m.rq , n .ddsj from
(select rq , count(1) cnt from a group by rq) m ,
(select * ,px = (select count(1) from a where rq = t.rq and ddsj < t.ddsj) + 1 from a t) n
where m.rq = n.rq and ((m.cnt%2 = 1 and n.px = m.cnt/2 + 1) or (m.cnt%2 = 0 and (n.px = m.cnt/2 or n.px = m.cnt/2 + 1)))
order by m.rq , ddsj

drop table a

/*
rq ddsj
-------- -----------
200805 30
200805 40
200806 200

(所影响的行数为 3 行)

*/
dawugui 2009-10-27
  • 打赏
  • 举报
回复
create table a(rq varchar(8), ddsj int)
insert into a
select
'200805',30 union all select
'200805',40 union all select
'200805',50 union all select
'200805',20 union all select
'200806',250 union all select
'200806',200 union all select
'200806',310 union all select
'200806',100 union all select
--'200806',300 union all select
'200806',130;

select m.rq , n .ddsj from
(select rq , count(1) cnt from a group by rq) m ,
(select * ,px = (select count(1) from a where rq = t.rq and ddsj < t.ddsj) + 1 from a t) n
where m.rq = n.rq and m.cnt%2 = 1 and n.px = m.cnt/2 + 1
union all
select m.rq , n .ddsj from
(select rq , count(1) cnt from a group by rq) m ,
(select * ,px = (select count(1) from a where rq = t.rq and ddsj < t.ddsj) + 1 from a t) n
where m.rq = n.rq and m.cnt%2 = 0 and (n.px = m.cnt/2 or n.px = m.cnt/2 + 1)
order by m.rq , ddsj

drop table a

/*
rq ddsj
-------- -----------
200805 30
200805 40
200806 200

(所影响的行数为 3 行)

*/
SQL77 2009-10-27
  • 打赏
  • 举报
回复
declare @a table(rq varchar(8), ddsj int)
insert into @a
select
'200805',30 union all select
'200805',40 union all select
'200805',50 union all select
'200805',20 union all select
'200806',250 union all select
'200806',200 union all select
'200806',310 union all select
'200806',100 union all select
--'200806',300 union all select
'200806',130;

select (select count(*) from @a where rq=t.rq and ddsj<=t.ddsj)as num ,*
into #t from @a t order by ddsj

select
t.*
from
#t t ,
(
select
(min(num)+max(num))/2 num,
ceiling((min(num)+max(num))*1.0/2)num1,rq
from
#t
group by rq)as t1

where (t.num=t1.num or t.num=t1.num1) and t.rq=t1.rq

num rq ddsj
----------- -------- -----------
2 200805 30
3 200805 40
3 200806 200

(所影响的行数为 3 行)
Shawn_1978 2009-10-27
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 feixianxxx 的回复:]
SQL code--方法2select rq,ddsjfrom
(select ROW_NUMBER()over(partitionby rqorderby ddsj)as rn1,COUNT(*)over(partitionby rq)as rn
,*from a ) kwhereabs(2*rn1-rn-1)<=1/*
rq ddsj
-------- -----------
2¡­
[/Quote]

这个牛!!!
致敬!
luoyoumou 2009-10-27
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 gsk09 的回复:]
ddsj 重复的要怎么处理?
[/Quote]

-----可以先看成:ddsj不重复!
Shawn_1978 2009-10-27
  • 打赏
  • 举报
回复
;with cte_final
as (
select rq,ddsj,COUNT(*) over(partition by rq) as cnt
,ROW_NUMBER() over(partition by rq order by ddsj ) as rn
from a
)
select rn,rq,ddsj
from cte_final
where rn = (case
when cnt%2=0 and rn=(cnt/2+1) then (cnt/2+1) --Mid+1
when cnt%2=0 and rn=(cnt/2) then (cnt/2) --Mid
else (cnt/2+1)
end)
gsk09 2009-10-27
  • 打赏
  • 举报
回复
跟feixianxxx的方法2重了
gsk09 2009-10-27
  • 打赏
  • 举报
回复


select a.rq,a.ddsj
from
(select
abs(row_number()over(partition by rq order by ddsj)
-(count(*)over(partition by rq)+1)/2.0) c
,*
from a)a
where c<1

SQL77 2009-10-27
  • 打赏
  • 举报
回复
来学习
gsk09 2009-10-27
  • 打赏
  • 举报
回复
哦,中间的行不是中间的值啊。看错了
gsk09 2009-10-27
  • 打赏
  • 举报
回复
ddsj 重复的要怎么处理?
lang071234 2009-10-27
  • 打赏
  • 举报
回复
都没看懂。
加载更多回复(15)

22,210

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧