根据该表中一个字段的MAX,从一个表中选择多个列

时间:2017-05-03 14:37:17

标签: sql-server

我一直在寻找这个问题的年龄并得到很多答案似乎回答了问题,但也许我只是没有“得到”它。我似乎无法将答案应用于我的特定问题。

我有一个查询列出了我们所有的学习者并提取了他们的所有历史记录(4种类型)或显示NULL,如果他们没有:

select LEARNERS.Learner_ID
       , LEARNERS.Firstname
       , LEARNERS.Surname
       , HISTORY.DateStart
       , HISTORY.Notes
from LEARNERS left outer join 
     HISTORY on 
         LEARNERS.Learner_ID = HISTORY.Learner_ID 
           and 
         HISTORY.Category_ID in (479,480,481,482) 
order by LEARNERS.Learner_ID

这很有效,但我只想查看每个学习者的最新历史(如果没有,请NULL),所以,在这里搜索之后,我试图这样做:

select LEARNERS.Learner_ID
       , LEARNERS.Firstname
       , LEARNERS.Surname
       , HISTORY.DateStart
       , HISTORY.Notes
from LEARNERS left outer join 
     (select MAX(DateStart) as LatestHistory, Learner_ID
      from HISTORY
      Where Category_ID in (479,480,481,482)
      group by Learner_ID) as LatestHistoryTable on 
         LEARNERS.Learner_ID = LatestHistoryTable.Learner_ID 

哪个作品非常出色,每个学习者只能获得一个历史记录(最新的一个)。然而;我真正需要的是历史表中的更多信息(例如History.Notes, History.Officer, History.DateStart)。

我尝试在子查询中添加更多列:

...
(select MAX(DateStart) as LatestHistory, Learner_ID, Notes, Officer
      from HISTORY
      Where Category_ID in (479,480,481,482)
      group by Learner_ID, Notes, Officer) as LatestHistoryTable
...

但是这给了我一个关于group by子句中的文本字段的错误:o(

我决定只将HistoryID字段然后INNER JOIN添加到子查询之外的HISTORY表中,以拉出我需要的其他字段:

...
(select MAX(DateStart) as LatestHistory, Learner_ID, HistoryID
      from HISTORY
      Where Category_ID in (479,480,481,482)
      group by Learner_ID, HistoryID) as LatestHistoryTable
...

但所做的只是为每个学习者生成多行(类似于我原来的查询),所以现在我很难过。

我确信这对于经验丰富的SQL编码器来说是一件简单的事情,因为它必须出现很多次,但我还在学习,所以我有点卡住我害怕。

谢谢, 艾伦

1 个答案:

答案 0 :(得分:0)

您可以使用row_number和desc,如下所示:

select LEARNERS.Learner_ID
       , LEARNERS.Firstname
       , LEARNERS.Surname
       , LatestHistoryTable.DateStart
       , LatestHistoryTable.Notes
from LEARNERS left outer join 
     ( select RowN = Row_Number() over(partition by Learner_id order by DateStart Desc), DateStart as LatestHistory, 
        Learner_ID, Notes, Officer  
        from HISTORY 
              Where Category_ID in (479,480,481,482)
              ) as LatestHistoryTable on 
         LEARNERS.Learner_ID = LatestHistoryTable.Learner_ID 
         AND LatestHistoryTable.RowN = 1