首页 > 解决方案 > 使用 dense_rank 查找列何时随时间变化

问题描述

以前曾经用dense_rank相同值的倍数来枚举行。但现在我想做基本上相同的事情,除了按更多行排序。基本上我有这个查询:

SELECT student_id_fk, Long_Desc, Term_Seq_Id, [semester index]
, DENSE_RANK() OVER (PARTITION BY student_id_fk ORDER BY Long_Desc ASC ) AS [major index]
FROM @semester_index AS si
ORDER BY Term_Seq_Id

此查询的最终目标是为学生每次更改专业时生成一个按时间顺序排列的排名。因此,当学生从数学转到土木工程时,major index将由 1 变为 2。

但是,当前的查询会产生此输出

student_id_fk   Long_Desc   Term_Seq_Id semester index  major index
1234    Mathematics         0934    1   2
1234    Mathematics         0936    2   2
1234    Civil Engineering   0942    3   1
1234    Civil Engineering   0944    4   1

但这会产生我想要的相反输出,因为它是Long_Desc按字母顺序按列排序的。我想要的是像这样按时间顺序排列:

student_id_fk   Long_Desc   Term_Seq_Id semester index  major index
1234    Mathematics         0934    1   1
1234    Mathematics         0936    2   1
1234    Civil Engineering   0942    3   2
1234    Civil Engineering   0944    4   2

我不确定如何以产生正确排名的方式对数据进行排序。

编辑:

我最终解决这个问题的方法是lagdense_rank.

标签: sqlsql-servertsql

解决方案


这对你有用吗?(获取每个专业的最大 TermSeqId 进行排序)

桌子:

Create Table #semidx
(
studentid_fk Int,
LongDesc VarChar(20),
TermSeqId char(4),
semidx Int
)
Insert Into #semidx Values

(1234,'Mathematics','0934',1),
(1234,'Mathematics','0936',2),
(1234,'Civil Engineering','0942',3),
(1234,'Civil Engineering','0944',4)

询问

SELECT 
   si.studentid_fk, 
   si.LongDesc, 
   TermSeqId, 
   semidx,
   DENSE_RANK() OVER (PARTITION BY si.studentid_fk ORDER BY si.LongDesc Asc ) AS [MajorIndex]
FROM #semidx AS si
Left Join
(
   Select studentid_fk, LongDesc, Max(TermSeqId) As tsi From #semidx
   Group By studentid_fk, LongDesc
)  As m 
   On m.studentid_fk = si.studentid_fk And m.LongDesc = si.LongDesc
   Order By tsi

更新:我还没有完全审查以下内容,但它似乎更接近我认为你所说的。下面对 Row Numbers by major 和 TermSeqId 之间的差异进行了密集排名

Select 
   studentid_fk,
   LongDesc,
   TermSeqId, 
   Dense_Rank() OVER (Partition By studentid_fk Order By rnk) As majoridx
From 
(
Select *, 
       ROW_NUMBER() OVER (ORDER BY TermSeqId) -
       ROW_NUMBER() OVER (PARTITION BY LongDesc ORDER BY TermSeqId) AS rnk
From
#semidx ) t
Order By studentid_fk, t.TermSeqId

推荐阅读