排名或Dense_Rank

时间:2017-08-30 15:04:03

标签: sql sql-server

我正在尝试为下面的数字指定“部分”。不确定Dense_Rank是否会起作用。基本上它应该由seq和UniqueLoc分配。因此它应该查看seq 0然后是UniqueLoc 99137-4529并分配部分1然后移动到seq 1如果UniqueLoc匹配它应该分配部分1如果不是然后部分2.下面是我的SQL和我的结果:你可以看到它是做密集排名,但不是我需要他们的顺序。它应该是1,2,3,3

UniqueLoc   seq loadnumber  SwineMovement   sectionrow  section
99137-4529  0   304360             304360          1     2
99137-4530  1   304360             3043601         1     1
99079-4530  2   304360             3043602         1     3
99079-4530  3   304360             3043603         2     3

select *,
DENSE_RANK () over ( partition by loadnumber, uniqueloc order by   seq )   as sectionrow ,
DENSE_RANK () over (  partition by Loadnumber   order by     uniqueloc desc )   as section 
from test
order by loadnumber, seq
    UniqueLoc   seq loadnumber  SwineMovement   dr  WHAT I NEED
    99137-4529  0   304360             304360   3   1
    99137-4530  1   304360            3043601   4   2
    99079-4530  2   304360            3043602   5   3
    99079-4530  3   304360            3043603   5   3
     2519-3982  0   304468            304468    2   1
     2632-3982  1   304468           3044681    1   2
   104004-8232  0   304873            304873    8   1
    104004-8232 1   304873           3048731    8   1
   104007-8035  2   304873           3048732    6   2
    104007-8035 3   304873           3048733    6   2
    104007-8232 4   304873           3048734    7   3
    104007-8232 5   304873           3048735    7   3

2 个答案:

答案 0 :(得分:1)

我认为排序应首先按UniqueLoc列中的最后四位数递增,然后是同一列降序的前五位数:

SELECT *,
    DENSE_RANK() OVER (PARTITION BY loadnumber
                       ORDER BY
                           SUBSTRING(UniqueLoc,
                           CHARINDEX('-', UniqueLoc) + 1,
                           LEN(UniqueLoc) - CHARINDEX('-', UniqueLoc)),
                           SUBSTRING(UniqueLoc, 1, CHARINDEX('-', UniqueLoc) - 1) DESC) dr
FROM test
ORDER BY
    loadnumber, seq;

您从未告诉我们您的数据库,但如果它支持LEFTRIGHT功能,那么您可以使用以下清理器ORDER BY

ORDER BY RIGHT(UniqueLoc, 4), LEFT(UniqueLoc, 5) DESC

<强>输出:

enter image description here

在这里演示:

Rextester

该演示在SQL Server中,因为我认为您的select *语法会失败,而Postgres可能是唯一的其他候选者。

答案 1 :(得分:0)

根据您的预期结果,排序将始终位于seq列

SELECT uniqueloc,
       seq,
       loadnumber,
       swinemovement,
       DENSE_RANK() OVER (PARTITION BY loadnumber 
                              ORDER BY CASE WHEN seq<> rnum
                                            THEN CONCAT(CAST(seq-rnum AS VARCHAR),uniqueloc)
                                            ELSE uniqueloc
                                        END) [rank]
  FROM (SELECT *,
               (ROW_NUMBER() OVER (PARTITION BY loadnumber 
                                       ORDER BY uniqueloc) - 1) rnum
          FROM t_load
       ) t
 ORDER BY loadnumber, 
          seq;

结果(我添加了测试数据loadnumber 900000以检查排名是否仍然适用于其他方案)

uniqueloc   seq loadnumber  swinemovement   rank
99137-4529  0   304360      304360          1
99137-4530  1   304360      3043601         2
99079-4530  2   304360      3043602         3
99079-4530  3   304360      3043603         3
2519-3982   0   304468      304468          1
2632-3982   1   304468      3044681         2
104004-8232 0   304873      304873          1
104004-8232 1   304873      3048731         1
104007-8035 2   304873      3048732         2
104007-8035 3   304873      3048733         2
104007-8232 4   304873      3048734         3
104007-8232 5   304873      3048735         3
99137-4529  0   900000      304360          1
99079-4530  1   900000      3043601         2
99079-4530  2   900000      3043602         2
99137-4530  3   900000      3043603         3