一个简单排名的问题

IntoWindy 2009-06-17 11:34:09
这是原始表
km1 km2 zwdm zf
75 70 303 145
74 66 304 140
65 74 303 139
75.5 63.5 304 139
68 69.5 303 137.5
71.5 65.5 304 137
65.5 66 304 131.5
63 68.5 304 131.5
66.5 65 303 131.5
68 63.5 304 131.5
65.5 65.5 303 131
68.5 62.5 303 131
66.5 64.5 303 131
67.5 63 304 130.5
65.5 65 303 130.5

想要的效果 按照(zwdm)职位+(zf)总分+km1来排序,并写入名次。
如果km1和km2总分在同一职位中相同,则随即选择一人名次在前。
km1 km2 zwdm zf mc
75 70 303 145 1
65 74 303 139 2
68 69.5 303 137.5 3
66.5 65 303 131.5 4
68.5 62.5 303 131 5
66.5 64.5 303 131 6
65.5 65.5 303 131 7
65.5 65 303 130.5 8
74 66 304 140 1
75.5 63.5 304 139 2
71.5 65.5 304 137 3
68 63.5 304 131.5 4
65.5 66 304 131.5 5
63 68.5 304 131.5 6
67.5 63 304 130.5 7
我自己写了点,并请教了些高手的,总有点问题,请教各位了。谢谢
...全文
36 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
百年树人 2009-06-17
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 IntoWindy 的回复:]
可是我这只能用SQLSERVER2000。
[/Quote]

---测试数据---
if object_id('[tb]') is not null drop table [tb]
go
create table [tb]([km1] numeric(3,1),[km2] numeric(3,1),[zwdm] int,[zf] numeric(4,1))
insert [tb]
select 75,70,303,145 union all
select 74,66,304,140 union all
select 65,74,303,139 union all
select 75.5,63.5,304,139 union all
select 68,69.5,303,137.5 union all
select 71.5,65.5,304,137 union all
select 65.5,66,304,131.5 union all
select 63,68.5,304,131.5 union all
select 66.5,65,303,131.5 union all
select 68,63.5,304,131.5 union all
select 65.5,65.5,303,131 union all
select 68.5,62.5,303,131 union all
select 66.5,64.5,303,131 union all
select 67.5,63,304,130.5 union all
select 65.5,65,303,130.5

---查询---
select tid=identity(int,1,1),* into # from [tb] order by zwdm,zf desc,km1 desc

select
km1,
km2,
zwdm,
zf,
mc=(select count(1)+1 from # where zwdm=t.zwdm and tid<t.tid)
from
# t
order by
zwdm,
mc

drop table #

---结果---
km1 km2 zwdm zf mc
----- ----- ----------- ------ -----------
75.0 70.0 303 145.0 1
65.0 74.0 303 139.0 2
68.0 69.5 303 137.5 3
66.5 65.0 303 131.5 4
68.5 62.5 303 131.0 5
66.5 64.5 303 131.0 6
65.5 65.5 303 131.0 7
65.5 65.0 303 130.5 8
74.0 66.0 304 140.0 1
75.5 63.5 304 139.0 2
71.5 65.5 304 137.0 3
68.0 63.5 304 131.5 4
65.5 66.0 304 131.5 5
63.0 68.5 304 131.5 6
67.5 63.0 304 130.5 7

(所影响的行数为 15 行)
--小F-- 2009-06-17
  • 打赏
  • 举报
回复
--测试下沟沟的
----------------------------------------------------------------
-- Author :fredrickhu(小F 向高手学习)
-- Date :2009-06-17 11:37:31
----------------------------------------------------------------
--> 测试数据:[ta]
if object_id('[ta]') is not null drop table [ta]
create table [ta]([km1] numeric(3,1),[km2] numeric(3,1),[zwdm] int,[zf] numeric(4,1))
insert [ta]
select 75,70,303,145 union all
select 74,66,304,140 union all
select 65,74,303,139 union all
select 75.5,63.5,304,139 union all
select 68,69.5,303,137.5 union all
select 71.5,65.5,304,137 union all
select 65.5,66,304,131.5 union all
select 63,68.5,304,131.5 union all
select 66.5,65,303,131.5 union all
select 68,63.5,304,131.5 union all
select 65.5,65.5,303,131 union all
select 68.5,62.5,303,131 union all
select 66.5,64.5,303,131 union all
select 67.5,63,304,130.5 union all
select 65.5,65,303,130.5
--------------开始查询--------------------------
select id=identity(int,1,1) ,* into #t
from ta
order by zwdm,zf desc,km1 desc

select km1,km2,zwdm,zf,mc=(select count(*) from #t where zwdm=A.zwdm and id<=A.id)
from #t as A

----------------结果----------------------------
/*
km1 km2 zwdm zf mc
---------------------- ---------------------- ----------- ---------------------- --------------------
75 70 303 145 1
68 69.5 303 137.5 2
65 74 303 139 3
68.5 62.5 303 131 4
66.5 65 303 131.5 5
66.5 64.5 303 131 6
65.5 65.5 303 131 7
65.5 65 303 130.5 8
75.5 63.5 304 139 1
74 66 304 140 2
71.5 65.5 304 137 3
68 63.5 304 131.5 4
67.5 63 304 130.5 5
65.5 66 304 131.5 6
63 68.5 304 131.5 7


*/
仙道彰 2009-06-17
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 playwarcraft 的回复:]
SQL code
create table T(km1 float, km2 float, zwdm int, zf float)
insert into T
select 75 ,70 ,303, 145
union all select 74, 66, 304, 140
union all select 65 ,74, 303, 139
union all select 75.5, 63.5, 304, 139
union all select 68, 69.5, 303, 137.5
union all select 71.5, 65.5, 304, 137
union all select 65.5, 66, 304, 131.5
union all select 63, 68.5, 304, 131.5
union all sele…
[/Quote]
playwarcraft 好强大,mark
惭愧
--小F-- 2009-06-17
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 playwarcraft 的回复:]
2000的例子不好,萬一km1再相同就不爽了,可以弄個臨時表

SQL code
--SQl2000
select id=identity(int,1,1) ,* into #t
from T
order by zwdm,zf desc,km1 desc

select km1,km2,zwdm,zf,mc=(select count(*) from #t where zwdm=A.zwdm and id<=A.id)
from #t as A
[/Quote]
...
ai_li7758521 2009-06-17
  • 打赏
  • 举报
回复
declare @t table(km1 float, km2 float, zwdm int, zf float) 
insert @t
select 75 ,70 ,303, 145
union all select 74, 66, 304, 140
union all select 65 ,74, 303, 139
union all select 75.5, 63.5, 304, 139
union all select 68, 69.5, 303, 137.5
union all select 71.5, 65.5, 304, 137
union all select 65.5, 66, 304, 131.5
union all select 63, 68.5, 304, 131.5
union all select 66.5, 65, 303, 131.5
union all select 68, 63.5, 304, 131.5
union all select 65.5, 65.5, 303, 131
union all select 68.5, 62.5, 303, 131
union all select 66.5, 64.5, 303, 131
union all select 67.5, 63, 304, 130.5
union all select 65.5, 65, 303, 130.5

select km1, km2, zwdm, zf,mc=DENSE_RANK() over(partition by zwdm order by zwdm+zf+km1 desc)
from @t

km1 km2 zwdm zf mc
---------------------- ---------------------- ----------- ---------------------- --------------------
75 70 303 145 1
68 69.5 303 137.5 2
65 74 303 139 3
68.5 62.5 303 131 4
66.5 65 303 131.5 5
66.5 64.5 303 131 6
65.5 65.5 303 131 7
65.5 65 303 130.5 8
75.5 63.5 304 139 1
74 66 304 140 2
71.5 65.5 304 137 3
68 63.5 304 131.5 4
67.5 63 304 130.5 5
65.5 66 304 131.5 6
63 68.5 304 131.5 7

(15 行受影响)
IntoWindy 2009-06-17
  • 打赏
  • 举报
回复
对,首先就要对zwdm分组,呵呵。
仙道彰 2009-06-17
  • 打赏
  • 举报
回复
貌似zwdm 行不是你想要的结果,在试试
playwarcraft 2009-06-17
  • 打赏
  • 举报
回复
2000的例子不好,萬一km1再相同就不爽了,可以弄個臨時表

--SQl2000
select id=identity(int,1,1) ,* into #t
from T
order by zwdm,zf desc,km1 desc

select km1,km2,zwdm,zf,mc=(select count(*) from #t where zwdm=A.zwdm and id<=A.id)
from #t as A
仙道彰 2009-06-17
  • 打赏
  • 举报
回复
use Practice
if object_id('tb1')is not null
drop table tb1
go
create table tb1 (km1 int, km2 int, zwdm int, zf int )
insert into tb1 select 75, 70, 303, 145
union select 75, 70, 303, 145
union select 74, 66, 304, 140
union select 65, 74, 303, 139
union select 75.5, 63.5, 304, 139
union select 68, 69.5, 303, 137.5
union select 71.5, 65.5, 304, 137
union select 65.5, 66, 304, 131.5
union select 63, 68.5, 304, 131.5
union select 66.5, 65, 303, 131.5
union select 68, 63.5, 304, 131.5
union select 65.5, 65.5, 303, 131
union select 68.5, 62.5, 303, 131
union select 66.5, 64.5, 303, 131
union select 67.5, 63, 304, 130.5
union select 65.5, 65, 303, 130.5
go
SELECT km1, km2, zwdm, zf,ROW_NUMBER() OVER(order by km1 desc,zwdm,zf desc) AS rownumber from tb1 order by km1 desc,zwdm,zf desc

drop table tb1
go

km1 km2 zwdm zf rownumber
----------- ----------- ----------- ----------- --------------------
75 70 303 145 1
75 63 304 139 2
74 66 304 140 3
71 65 304 137 4
68 69 303 137 5
68 62 303 131 6
68 63 304 131 7
67 63 304 130 8
66 64 303 131 9
66 65 303 131 10
65 74 303 139 11
65 65 303 131 12
65 65 303 130 13
65 66 304 131 14
63 68 304 131 15

(15 行受影响)

Freeid_shi 2009-06-17
  • 打赏
  • 举报
回复
declare @zw varchar(20)
declare mysor CURSOR FOR
select distinct zwdm from 原始表 with(nolock)
open mysor
fetch next from mysor into @zw
while (@@fetch_status=0)
begin
select km1,km2,zwdm,zf,mc=identity(int,1,1)
into #temp
from 原始表 with(nolock)
where zwdm=@zw
order by zf
fetch next from mysor into @zwend
end
close mysor
deallocate mysor
select *from #temp
drop table #temp
IntoWindy 2009-06-17
  • 打赏
  • 举报
回复
可是我这只能用SQLSERVER2000。
ai_li7758521 2009-06-17
  • 打赏
  • 举报
回复
select km1, km2, zwdm, zf,mc=rank() over(order by zwdm+zf+km1)
from tb
playwarcraft 2009-06-17
  • 打赏
  • 举报
回复

create table T(km1 float, km2 float, zwdm int, zf float)
insert into T
select 75 ,70 ,303, 145
union all select 74, 66, 304, 140
union all select 65 ,74, 303, 139
union all select 75.5, 63.5, 304, 139
union all select 68, 69.5, 303, 137.5
union all select 71.5, 65.5, 304, 137
union all select 65.5, 66, 304, 131.5
union all select 63, 68.5, 304, 131.5
union all select 66.5, 65, 303, 131.5
union all select 68, 63.5, 304, 131.5
union all select 65.5, 65.5, 303, 131
union all select 68.5, 62.5, 303, 131
union all select 66.5, 64.5, 303, 131
union all select 67.5, 63, 304, 130.5
union all select 65.5, 65, 303, 130.5

--SQL2005
select km1, km2, zwdm ,zf , row_number() over (partition by zwdm order by zf desc,km1 desc) as mc
from T
GO
/*
75 70 303 145 1
65 74 303 139 2
68 69.5 303 137.5 3
66.5 65 303 131.5 4
68.5 62.5 303 131 5
66.5 64.5 303 131 6
65.5 65.5 303 131 7
65.5 65 303 130.5 8
74 66 304 140 1
75.5 63.5 304 139 2
71.5 65.5 304 137 3
68 63.5 304 131.5 4
65.5 66 304 131.5 5
63 68.5 304 131.5 6
67.5 63 304 130.5 7

*/

--SQl2000
select km1,km2,zwdm,zf,mc=mc-(select count(*) from T where zwdm=B.zwdm and zf=B.zf and km1<=B.km1)+1
from
(
select km1,km2,zwdm,zf,mc=(select count(*) from T where zwdm=A.zwdm and zf>=A.zf)
from T as A
) B
order by zwdm,mc

--
drop table T

lgx0914 2009-06-17
  • 打赏
  • 举报
回复
参考下吧
ROW_NUMBER、RANK、DENSE_RANK的用法
(爱新觉罗.毓华(十八年风雨,守得冰山雪莲花开) 2007-12-16 广东深圳)

SQL Server 2005 引入几个新的排序(排名)函数,如ROW_NUMBER、RANK、DENSE_RANK等。
这些新函数使您可以有效地分析数据以及向查询的结果行提供排序值。

--------------------------------------------------------------------------
ROW_NUMBER()

说明:返回结果集分区内行的序列号,每个分区的第一行从 1 开始。
语法:ROW_NUMBER () OVER ( [ <partition_by_clause> ] <order_by_clause> ) 。
备注:ORDER BY 子句可确定在特定分区中为行分配唯一 ROW_NUMBER 的顺序。
参数:<partition_by_clause> :将 FROM 子句生成的结果集划入应用了 ROW_NUMBER 函数的分区。
<order_by_clause>:确定将 ROW_NUMBER 值分配给分区中的行的顺序。
返回类型:bigint 。

示例:
/*以下示例将根据年初至今的销售额,返回 AdventureWorks 中销售人员的 ROW_NUMBER。*/

USE AdventureWorks
GO
SELECT c.FirstName, c.LastName, ROW_NUMBER() OVER(ORDER BY SalesYTD DESC) AS 'Row Number', s.SalesYTD, a.PostalCode
FROM Sales.SalesPerson s JOIN Person.Contact c on s.SalesPersonID = c.ContactID
JOIN Person.Address a ON a.AddressID = c.ContactID
WHERE TerritoryID IS NOT NULL AND SalesYTD <> 0
/*
FirstName LastName Row Number SalesYTD PostalCode
--------- ---------- ---------- ------------ ----------------------------
Shelley Dyck 1 5200475.2313 98027
Gail Erickson 2 5015682.3752 98055
Maciej Dusza 3 4557045.0459 98027
Linda Ecoffey 4 3857163.6332 98027
Mark Erickson 5 3827950.238 98055
Terry Eminhizer 6 3587378.4257 98055
Michael Emanuel 7 3189356.2465 98055
Jauna Elson 8 3018725.4858 98055
Carol Elliott 9 2811012.7151 98027
Janeth Esteves 10 2241204.0424 98055
Martha Espinoza 11 1931620.1835 98055
Carla Eldridge 12 1764938.9859 98027
Twanna Evans 13 1758385.926 98055
(13 行受影响)
*/

/*以下示例将返回行号为 50 到 60(含)的行,并以 OrderDate 排序。*/
USE AdventureWorks;
GO
WITH OrderedOrders AS
(SELECT SalesOrderID, OrderDate,
ROW_NUMBER() OVER (order by OrderDate)as RowNumber
FROM Sales.SalesOrderHeader )
SELECT *
FROM OrderedOrders
WHERE RowNumber between 50 and 60;
/*
SalesOrderID OrderDate RowNumber
------------ ----------------------- --------------------
43708 2001-07-03 00:00:00.000 50
43709 2001-07-03 00:00:00.000 51
43710 2001-07-03 00:00:00.000 52
43711 2001-07-04 00:00:00.000 53
43712 2001-07-04 00:00:00.000 54
43713 2001-07-05 00:00:00.000 55
43714 2001-07-05 00:00:00.000 56
43715 2001-07-05 00:00:00.000 57
43716 2001-07-05 00:00:00.000 58
43717 2001-07-05 00:00:00.000 59
43718 2001-07-06 00:00:00.000 60
(11 行受影响)
*/

--------------------------------------------------------------
RANK()

说明:返回结果集的分区内每行的排名。行的排名是相关行之前的排名数加一。
语法:RANK () OVER ( [ < partition_by_clause > ] < order_by_clause > )
备注:如果两个或多个行与一个排名关联,则每个关联行将得到相同的排名。
例如,如果两位顶尖销售员具有同样的 SalesYTD 值,他们将并列第一。
由于已有两行排名在前,所以具有下一个最大 SalesYTD 的销售人员将排名第三。
因此,RANK 函数并不总返回连续整数。
用于整个查询的排序顺序决定了行在结果集中的显示顺序。这也隐含了行在每个分区中的排名。
参数:< partition_by_clause > :将 FROM 子句生成的结果集划分为要应用 RANK 函数的分区。
< order_by_clause >:确定将 RANK 值应用于分区中的行时所基于的顺序。
返回类型:bigint

示例:
/*以下示例按照数量对清单中的产品进行了排名。行集按 LocationID 分区,按 Quantity 排序。
USE AdventureWorks;
GO
SELECT i.ProductID, p.Name, i.LocationID, i.Quantity, RANK() OVER (PARTITION BY i.LocationID order by i.Quantity) as RANK
FROM Production.ProductInventory i JOIN Production.Product p
ON i.ProductID = p.ProductID
ORDER BY p.Name
GO
/*
ProductID Name LocationID Quantity RANK
----------- -------------------------------------------------- ---------- -------- --------------------
1 Adjustable Race 6 324 71
1 Adjustable Race 1 408 78
1 Adjustable Race 50 353 117
2 Bearing Ball 6 318 67
2 Bearing Ball 1 427 85
2 Bearing Ball 50 364 122
3 BB Ball Bearing 50 324 106
3 BB Ball Bearing 1 585 110
3 BB Ball Bearing 6 443 115
4 Headset Ball Bearings 1 512 99
4 Headset Ball Bearings 6 422 108
4 Headset Ball Bearings 50 388 140
316 Blade 10 388 33
......
(1069 行受影响)
*/
DENSE_RANK()

说明:返回结果集分区中行的排名,在排名中没有任何间断。行的排名等于所讨论行之前的所有排名数加一。
语法:DENSE_RANK () OVER ( [ < partition_by_clause > ] < order_by_clause > )
备注:如果有两个或多个行受同一个分区中排名的约束,则每个约束行将接收相同的排名。
例如,如果两位顶尖销售员具有相同的 SalesYTD 值,则他们将并列第一。
接下来 SalesYTD 最高的销售人员排名第二。该排名等于该行之前的所有行数加一。
因此,DENSE_RANK 函数返回的数字没有间断,并且始终具有连续的排名。
整个查询所用的排序顺序确定了各行在结果中的显示顺序。这说明排名第一的行可以不是分区中的第一行。
参数:< partition_by_clause > :将 FROM 子句所生成的结果集划分为数个将应用 DENSE_RANK 函数的分区。
< order_by_clause >:确定将 DENSE_RANK 值应用于分区中各行的顺序。
返回类型:bigint

示例:
/*以下示例返回各位置上产品数量的 DENSE_RANK。 */
USE AdventureWorks;
GO
SELECT i.ProductID, p.Name, i.LocationID, i.Quantity, DENSE_RANK() OVER (PARTITION BY i.LocationID order by i.Quantity) as DENSE_RANK
FROM Production.ProductInventory i JOIN Production.Product p ON i.ProductID = p.ProductID
ORDER BY Name;
GO
/*
ProductID Name LocationID Quantity DENSE_RANK
----------- -------------------------------------------------- ---------- -------- --------------------
1 Adjustable Race 1 408 57
1 Adjustable Race 6 324 52
1 Adjustable Race 50 353 82
879 All-Purpose Bike Stand 7 144 34
712 AWC Logo Cap 7 288 38
3 BB Ball Bearing 50 324 74
3 BB Ball Bearing 6 443 81
3 BB Ball Bearing 1 585 82
*/

-------------------------------------------------------------------------------------------------------
将上面三个函数放在一起计算,更能明显看出各个函数的功能。

CREATE TABLE rankorder(orderid INT,qty INT)
INSERT rankorder VALUES(30001,10)
INSERT rankorder VALUES(10001,10)
INSERT rankorder VALUES(10006,10)
INSERT rankorder VALUES(40005,10)
INSERT rankorder VALUES(30003,15)
INSERT rankorder VALUES(30004,20)
INSERT rankorder VALUES(20002,20)
INSERT rankorder VALUES(20001,20)
INSERT rankorder VALUES(10005,30)
INSERT rankorder VALUES(30007,30)
INSERT rankorder VALUES(40001,40)
INSERT rankorder VALUES(30007,30)
GO
--对一个列qty进行的排序
SELECT orderid,qty,
ROW_NUMBER() OVER(ORDER BY qty) AS rownumber,
RANK() OVER(ORDER BY qty) AS rank,
DENSE_RANK() OVER(ORDER BY qty) AS denserank
FROM rankorder
ORDER BY qty
/*
orderid qty rownumber rank denserank
----------- ----------- -------------------- -------------------- --------------------
30001 10 1 1 1
10001 10 2 1 1
10006 10 3 1 1
40005 10 4 1 1
30003 15 5 5 2
30004 20 6 6 3
20002 20 7 6 3
20001 20 8 6 3
10005 30 9 9 4
30007 30 10 9 4
30007 30 11 9 4
40001 40 12 12 5
(12 行受影响)
*/

--对两个列qty,orderid进行的排序
SELECT orderid,qty,
ROW_NUMBER() OVER(ORDER BY qty,orderid) AS rownumber,
RANK() OVER(ORDER BY qty,orderid) AS rank,
DENSE_RANK() OVER(ORDER BY qty,orderid) AS denserank
FROM rankorder
ORDER BY qty,orderid
drop table rankorder
/*
orderid qty rownumber rank denserank
----------- ----------- -------------------- -------------------- --------------------
10001 10 1 1 1
10006 10 2 2 2
30001 10 3 3 3
40005 10 4 4 4
30003 15 5 5 5
20001 20 6 6 6
20002 20 7 7 7
30004 20 8 8 8
10005 30 9 9 9
30007 30 10 10 10
30007 30 11 10 10
40001 40 12 12 11
(12 行受影响)

仙道彰 2009-06-17
  • 打赏
  • 举报
回复
帮顶,看看

34,592

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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