使用density_rank查找列的时间变化

时间:2019-02-01 13:50:26

标签: sql sql-server tsql

我有previously used dense_rank to enumerate rows with multiples of the same values。但是现在我想做基本上相同的事情,除了按更多行排序。基本上我有这个查询:

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结合使用。

2 个答案:

答案 0 :(得分:1)

这对您有用吗? (抓取每个专业的最大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

更新:我还没有完全审查以下内容,但它似乎与我想您所说的更加接近。下面对按专业划分的行号与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

答案 1 :(得分:-1)

您必须按Semister索引而不是long_desc来排序结果集。

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