繁体   English   中英

SQL使用多个组选择最新行

[英]SQL select latest row using multiple groups

我试图从强制执行的SQL程序中提取一些自定义报告,这些报告超出了我们在工作中必须使用的报告,并且遇到了一些问题。 我可以轻松提取所有我需要的数据,但是对于每个唯一的人员ID /任务ID组合,我只需要最新的值即可。 另外,如果可能的话,我希望从到期日或豁免日期列中取较大值作为最新值。


    PersonnelTrainingEvent PersonnelID  TrainingEventTypeID DueDate   WaiverDate    Personnel ID    TrainingEventType ID    Taskcode    PersonnelDetail PersonnelID   
    5351                                25947               1/1/1900  1/1/1900      5351            25947                   Mob2        5351  
    5351                                28195               8/1/2012  1/1/1900      5351            28195                   CA01        5351  
    5351                                26551               7/29/2010 1/1/1900      5351            26551                   Mob10       5351  
    5351                                25947               1/31/2012 1/1/1900      5351            25947                   Mob2        5351  
    5351                                28196               11/1/2012 1/1/1900      5351            28196                   CA02        5351  
    5418                                28195               1/1/1900  1/1/1900      5418            28195                   CA01        5418  
    5418                                30174               1/1/1900  1/1/1900      5418            30174                   PJ18        5418  
    5418                                28624               1/31/2014 2/1/2014      5418            28624                   GA42        5418  
    5418                                28595               6/30/2014 6/30/2014     5418            28595                   GA43        5418  
    5418                                28196               1/1/1900  1/1/1900      5418            28196                   CA02        5418  
    6022                                28195               3/3/2011  1/1/1900      6022            28195                   CA01        6022  
    6022                                28885               10/31/20121/1/1900      6022            28885                   CA07        6022  
    6022                                28884               1/1/1900  1/1/1900      6022            28884                   CA06        6022  
    6022                                28884               1/31/1901 1/1/1900      6022            28884                   CA06        6022  
    6022                                28196               1/1/1900  1/1/1900      6022            28196                   CA02        6022  
    6022                                28196               2/28/2011 1/1/1900      6022            28196                   CA02        6022  
    6022                                28624               9/30/2013 1/1/1900      6022            28624                   GA42        6022  
    6022                                28595               2/28/2014 1/1/1900      6022            28595                   GA43        6022  
    6022                                30174               2/28/2014 1/1/1900      6022            30174                   PJ18        6022  

这是我正在使用的查询...

SELECT
  PersonnelTrainingEvent.PersonnelID AS [PersonnelTrainingEvent PersonnelID]  
  ,PersonnelTrainingEvent.TrainingEventTypeID  
  ,PersonnelTrainingEvent.DueDate  
  ,PersonnelTrainingEvent.WaiverDate  
  ,Personnel.ID AS [Personnel ID]  
  ,TrainingEventType.ID AS [TrainingEventType ID]  
  ,TrainingEventType.Taskcode  
  ,PersonnelDetail.PersonnelID AS [PersonnelDetail PersonnelID]  
FROM  
  PersonnelTrainingEvent  
  INNER JOIN TrainingEventType  
    ON PersonnelTrainingEvent.TrainingEventTypeID = TrainingEventType.ID  
  INNER JOIN Personnel  
    ON PersonnelTrainingEvent.PersonnelID = Personnel.ID  
  INNER JOIN PersonnelDetail  
    ON Personnel.ID = PersonnelDetail.PersonnelID  
WHERE  
  TrainingEventType.Taskcode IN (N'GA43', N'MOB2', N'CA01', N'CA02', N'Mob10', N'PJ67', N'CA06', N'CA07', N'T104', N'GA42', N'PJ18')  
Group By  
  Personnel.ID, TrainingEventType.Taskcode;  

我目前正在休假,并被我的妻子怒视,但我已经对该查询进行了3个星期的调查,而且我的头撞在墙上。 我在下面提供了首选结果的示例...


    PersonnelTrainingEvent PersonnelID  TrainingEventTypeID DueDate   WaiverDate    Personnel ID    TrainingEventType ID    Taskcode    PersonnelDetail PersonnelID   
    5351                                28195               8/1/2012  1/1/1900      5351            28195                   CA01        5351  
    5351                                26551               7/29/2010 1/1/1900      5351            26551                   Mob10       5351  
    5351                                25947               1/31/2012 1/1/1900      5351            25947                   Mob2        5351  
    5351                                28196               11/1/2012 1/1/1900      5351            28196                   CA02        5351  
    5418                                28195               1/1/1900  1/1/1900      5418            28195                   CA01        5418  
    5418                                30174               1/1/1900  1/1/1900      5418            30174                   PJ18        5418  
    5418                                28624               1/31/2014 2/1/2014      5418            28624                   GA42        5418  
    5418                                28595               6/30/2014 6/30/2014     5418            28595                   GA43        5418  
    5418                                28196               1/1/1900  1/1/1900      5418            28196                   CA02        5418  
    6022                                28195               3/3/2011  1/1/1900      6022            28195                   CA01        6022  
    6022                                28885               10/31/20121/1/1900      6022            28885                   CA07        6022  
    6022                                28884               1/31/1901 1/1/1900      6022            28884                   CA06        6022  
    6022                                28196               2/28/2011 1/1/1900      6022            28196                   CA02        6022  
    6022                                28624               9/30/2013 1/1/1900      6022            28624                   GA42        6022  
    6022                                28595               2/28/2014 1/1/1900      6022            28595                   GA43        6022  
    6022                                30174               2/28/2014 1/1/1900      6022            30174                   PJ18        6022  


这是我看过的其他答案的链接,但我是一个做人的学习者,这些似乎有所帮助,但我不了解所有语法...

SQL选择,基于多个条件的特定行?
SQL Server仅使用最新值选择不同的行
SQL选择分组依据和日期排序
SQL Server使用特定日期之前的值选择不同的行
如何只为每个用户选择最新行?
从SQL Server中的JOIN结果获取不同的行
http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=47479
选择子组中的最新行

感谢您在自己学习中所做的任何帮助。 如果我增加了代表人数,我将提供所要求的任何输入或屏幕截图。 谢谢!

使用通用表格表达式

这是对需求的查询。

WITH cte ( personneltrainingeventpersonnelid, trainingeventtypeid, duedate, 
     waiverdate, personnelid, taskcode, personneldetailpersonnelid, dupcount) 
     AS (SELECT personneltrainingeventpersonnelid, 
                trainingeventtypeid, 
                duedate, 
                waiverdate, 
                personnelid, 
                taskcode, 
                personneldetailpersonnelid, 
                Row_number() 
                  OVER( 
                    partition BY personnelid 
                    ORDER BY duedate, waiverdate) AS DupCount 
         FROM   personneltrainingevent) 
SELECT C.* 
FROM   cte C, 
       (SELECT personneltrainingeventpersonnelid, 
               personnelid, 
               Max(duedate) AS Maximum 
        FROM   cte 
        GROUP  BY personnelid, 
                  personneltrainingeventpersonnelid) CC 
WHERE  C.personnelid = cc.personnelid 
       AND C.personneltrainingeventpersonnelid = 
           cc.personneltrainingeventpersonnelid 
       AND c.duedate = CC.maximum 
ORDER  BY C.personnelid 

可能想要的是这样的东西:

SELECT Event.personnelId, Event.trainingEventTypeId, Event.dueDate, Event.waiverDate,
       Event.taskCode
FROM (SELECT Event.personnelId, Event.trainingEventTypeId, Event.dueDate, Event.waiverDate,
             TrainingEventType.taskCode
             ROW_NUMBER() OVER(PARTITION BY Event.personnelId, Event.trainingEventTypeId
                               ORDER BY CASE WHEN Event.dueDate >= Event.waiverDate
                                             THEN Event.dueDate
                                             ELSE Event.waiverDate END DESC) rn
      FROM PersonnelTrainingEvent Event
      JOIN TrainingEventType
        ON TrainingEventType.id = Event.trainingEventTypeId
           AND TrainingEventType.taskCode IN (N'GA43', N'MOB2', N'CA01', N'CA02', N'Mob10', N'PJ67', N'CA06', N'CA07', N'T104', N'GA42', N'PJ18')) Event
WHERE Event.rn = 1  

但是,很难说出来,因为您提供的查询存在语法错误,具有不需要的其他列,并且引用了不应影响结果的表(这些表可能至少有一行,但是这些表中没有数据引用,通常不需要多行)。

感谢您提供的所有帮助,但我又回到了基础知识。 我将联接表切出,转到没有翻译数据所需的基本四列。 这样做之后,我看到该表仅创建具有1900 date字段的重复条目,因此我仅使用WHERE子句删除了多余的条目。 我对Clockwork-Muse的方法非常感兴趣,但是我一直收到没有意义的语法错误,一旦我看到了这个问题,我得到的是更少的剥离我所需内容的代码。 再次感谢您的支持和信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM