我有一些学生在多个报告期内都有报告分数。我使用以下SQL语句来获取这些报告标记
SELECT DISTINCT ID, thePeriod, MeritRank
FROM
(
SELECT ID,
cast(fileyear as varchar) + cast(filesemester as varchar) as thePeriod,
MeritRank
FROM uNCStudentMeritList) usm
ORDER BY ID, thePeriod asc
这给了我以下数据
我希望有另一列具有每行之间的差异,由ID号分隔。例如
注意:每个StudentId的第一个值项都留空,因为这是他们收到的第一个报告标记。从那时起,我希望看到一个报告标记与下一个报告标记之间的区别。如果他们收到了更糟糕的报告标记,那么它应该是如图所示的负数。我没有行ID号或表中的任何内容 - 我已经看到使用行ID号回答其他类似类型的问题。我怎样才能得到我之后的那种结果>
非常感谢任何帮助。
答案 0 :(得分:1)
试试这个:
;WITH cte_getdata
AS (SELECT ID,
Cast(fileyear AS VARCHAR(10))
+ Cast(filesemester AS VARCHAR(10)) AS thePeriod,
MeritRank,
ROW_NUMBER()
OVER (
partition BY id
ORDER BY Cast(fileyear AS VARCHAR(10)) ASC, Cast(filesemester AS VARCHAR(10)) ASC) AS rn
FROM uNCStudentMeritList)
SELECT t1.*,
t1.MeritRank - t2.MeritRank
FROM cte_getdata t1
LEFT JOIN cte_getdata t2
ON t1.rn = t2.rn + 1
AND t1.id = t2.id
Row_Number()
函数会为id
的分区中的每条记录分配唯一编号,并为fileyear,filesemester
的顺序分配唯一编号,然后您可以left join
自己的结果集并匹配当前行其前一行具有相同的id
。无论匹配条件如何,使用Left Join
都会为您提供所有行。以下是两个CTE
:
;WITH cte1
AS (SELECT ID,
Cast(fileyear AS VARCHAR)
+ Cast(filesemester AS VARCHAR) AS thePeriod,
MeritRank
FROM uNCStudentMeritList),
cte2
AS (SELECT *,
ROW_NUMBER()
OVER (
partition BY ID
ORDER BY thePeriod) rn
FROM cte1)
SELECT *
FROM cte2 c1
LEFT JOIN cte2 c2
ON c1.id = c2.id
AND c1.rn = c2.rn + 1
答案 1 :(得分:1)
试试这个。
;WITH cte
AS (SELECT Row_number()OVER (partition BY id ORDER BY theperiod) rn,
*
FROM tablename)
SELECT a.id,
a.theperiod,
a.MeritRank,
a.MeritRank - b.MeritRank
FROM cte A
LEFT JOIN cte b
ON a.rn = b.rn + 1
如果您正在使用SQL SERVER 2012+
,请尝试此操作。
SELECT id,
theperiod,
MeritRank,
Lag(MeritRank)
OVER (
partition BY id
ORDER BY theperiod) - MeritRank
FROM tablename
答案 2 :(得分:0)
这也应该有效:
SELECT usm1.ID, usm1.thePeriod, usm1.MeritRank, usm2.difference
FROM (SELECT ID, cast(fileyear as varchar) + cast(filesemester as varchar) as thePeriod, MeritRank
FROM uNCStudentMeritList)usm1 LEFT OUTER JOIN
(SELECT usm3.ID as ID, usm3.thePeriod as thePeriod, max(usm4.thePeriod), (usm3.MeritRank - usm4.MeritRank) as difference
FROM (SELECT ID, cast(fileyear as varchar) + cast(filesemester as varchar) as thePeriod, MeritRank
FROM uNCStudentMeritList)usm3 JOIN
(SELECT ID, cast(fileyear as varchar) + cast(filesemester as varchar) as thePeriod, MeritRank
FROM uNCStudentMeritList)usm4 USING (ID)
WHERE usm3.thePeriod > usm4.thePeriod
GROUP BY usm3.ID, usm3.thePeriod)usm2 USING (ID, thePeriod)