历史性的'切片'表

时间:2016-01-25 01:09:02

标签: sql sql-server tsql distinct

Ms SQL Server。

我有一张表来监控学生申请的状态。 学生可以申请多所学校,每个学生都可以接受/拒绝/等候学生。

tblApplicantSchools看起来像这样:

ApplicantID    |    SchoolID     |     StatusID

独特的申请人可以在这里申请多个学校 - 但每个学校申请只有一个状态。

我还有一个历史记录表tblApplicantSchools_shadow,它会影响tblApplicantSchools上所做的任何更改。它与上面的相同,只是它还节省了更改的时间,以及它是否是原始表上的插入/更新/删除。 所以在他shadow表中,可能有多个学生,多个学校有多种状态(当他们在整个过程中移动时)。

我想做的是将shadow表格分割到特定日期,并将每个申请的最新statusID单个记录到每个申请人的每个学校。这有意义吗? 例如:

ApplicantID    |    SchoolID     |     StatusID       |    ChangeDate
-----------------------------------------------------------------------
    11                   2                 3                  22/1/2015
    11                   2                 4                  30/1/2015
    11                   3                 4                  25/1/2015
    11                   3                 6                  29/1/2015

所以我想看到的只是上面的第2行和第4行,因为它们是每个学校最近一次申请人#11的最新更新。

有人可以给我一个关于如何做到这一点的指针吗?我的设置有点复杂,但我认为这个例子简化了它,因此问题很明确。

由于

2 个答案:

答案 0 :(得分:2)

您可以使用窗口函数ROW_NUMBER

SELECT *
FROM (SELECT *, rn = ROW_NUMBER() OVER(PARTITION BY ApplicantID,SchoolID  
                                       ORDER BY ChangeDate DESC)
      FROM tblApplicantSchools_shadow) AS sub
WHERE rn = 1;

LiveDemo

输出:

╔═════════════╦══════════╦══════════╦═════════════════════╗
║ ApplicantID ║ SchoolID ║ StatusID ║     ChangeDate      ║
╠═════════════╬══════════╬══════════╬═════════════════════╣
║          11 ║        2 ║        4 ║ 2015-01-30 00:00:00 ║
║          11 ║        3 ║        6 ║ 2015-01-29 00:00:00 ║
╚═════════════╩══════════╩══════════╩═════════════════════╝

请注意,如果ChangeDate仅为DATE(没有时间标准,则可能会出现平局,您应该使用RANK()DATETIME出现概率public void selection (){ final ListView lv = (ListView)findViewById(R.id.treeQuestionsList); Intent intent = getIntent(); int id2 = intent.getIntExtra("id2", 0); SparseBooleanArray checked = lv.getCheckedItemPositions(); int size = checked.size(); for (int i = 0; i < size; i++) { int key = checked.keyAt(i); entries.add(new Observation(id2,lv.getCheckedItemPositions().get(key))); Log.d(Constants.TAG,"--ID:="+id2+"--checkeddata----"+ entries.get(i).answers); } } 很低。

答案 1 :(得分:1)

如果您更喜欢符合ANSI-92标准的解决方案,或者您害怕窗口函数,那么此查询可能很有用:

SELECT s1.ApplicantID, s1.SchoolID, s1.StatusID, s1.ChangeDate
FROM shadow s1
INNER JOIN
(
    SELECT ApplicantID, SchoolID, MAX(ChangeDate) AS maxDate
    FROM shadow
    GROUP BY ApplicantID, SchoolID
) s2
ON s1.ApplicantID = s2.ApplicantID AND s1.SchoolID = s2.SchoolID
    AND s1.ChangeDate = s2.maxDate