这是原始表
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
我自己写了点,并请教了些高手的,总有点问题,请教各位了。谢谢

解决方案 »

  1.   

    参考下吧
    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 行受影响)
      

  2.   


    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
      

  3.   

    select km1, km2, zwdm, zf,mc=rank() over(order by zwdm+zf+km1)
    from tb
      

  4.   

    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
      

  5.   

    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 descdrop 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 行受影响)
      

  6.   

    2000的例子不好,萬一km1再相同就不爽了,可以弄個臨時表 --SQl2000
    select id=identity(int,1,1) ,* into #t 
    from T
    order by zwdm,zf desc,km1 descselect km1,km2,zwdm,zf,mc=(select count(*) from #t where zwdm=A.zwdm and id<=A.id)
    from #t as A
      

  7.   

    貌似zwdm 行不是你想要的结果,在试试
      

  8.   

    对,首先就要对zwdm分组,呵呵。
      

  9.   

    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 @tkm1                    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 行受影响)
      

  10.   

    playwarcraft 好强大,
    惭愧
      

  11.   

    --测试下沟沟的
    ----------------------------------------------------------------
    -- 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 descselect 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
    */
      

  12.   


    ---测试数据---
    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 descselect 
      km1,
      km2,
      zwdm,
      zf,
      mc=(select count(1)+1 from # where zwdm=t.zwdm and tid<t.tid)
    from
      # t
    order by
      zwdm,
      mcdrop 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 行)