简体   繁体   English

SQL使用多个组选择最新行

[英]SQL select latest row using multiple groups

I'm attempting to pull some custom reports from a mandated SQL program than we must use at work and I'm running into a couple issues. 我试图从强制执行的SQL程序中提取一些自定义报告,这些报告超出了我们在工作中必须使用的报告,并且遇到了一些问题。 I can pull all the data I need easily but for each unique person id/task id combination I only need the most current value. 我可以轻松提取所有我需要的数据,但是对于每个唯一的人员ID /任务ID组合,我只需要最新的值即可。 Additionally, if possible I want the latest value from either the due date or the waiver date column whichever is greater. 另外,如果可能的话,我希望从到期日或豁免日期列中取较大值作为最新值。


    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  

Here is the query I'm using... 这是我正在使用的查询...

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;  

I'm currently on vacation and getting glared at by my wife but I've been working on this query for 3 weeks now and I'm pounding my head against the wall. 我目前正在休假,并被我的妻子怒视,但我已经对该查询进行了3个星期的调查,而且我的头撞在墙上。 I've included a sample of the preferred outcome below... 我在下面提供了首选结果的示例...


    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  


Here are the links to the other answers I've looked at but I'm a learn by doing kinda guy and these seemed to help a little but I'm not understanding all the syntax... 这是我看过的其他答案的链接,但我是一个做人的学习者,这些似乎有所帮助,但我不了解所有语法...

SQL Select, Specific Rows based on multiple conditions? SQL选择,基于多个条件的特定行?
SQL server select distinct rows using most recent value only SQL Server仅使用最新值选择不同的行
SQL Select with Group By and Order By Date SQL选择分组依据和日期排序
SQL server select distinct rows using values before a certain date SQL Server使用特定日期之前的值选择不同的行
How to select only the latest rows for each user? 如何只为每个用户选择最新行?
Get Distinct rows from a result of JOIN in SQL Server 从SQL Server中的JOIN结果获取不同的行
http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=47479 http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=47479
Selecting latest rows in subgroups 选择子组中的最新行

I appreciate any help as I'm working to learn to do this myself. 感谢您在自己学习中所做的任何帮助。 I will provide any input requested or a screenshot if I increase my rep enough to allow that. 如果我增加了代表人数,我将提供所要求的任何输入或屏幕截图。 Thanks! 谢谢!

Use Common tabular Expression 使用通用表格表达式

Here is the query for the requirement. 这是对需求的查询。

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 

What you probably want is something like this: 可能想要的是这样的东西:

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  

However, it's difficult to tell because the query you've provided has syntax errors, has additional unneeded columns, and references tables which should not influence the results (the tables are likely to have at least one row, but no data from those tables is referenced, and multiple rows are usually unwanted). 但是,很难说出来,因为您提供的查询存在语法错误,具有不需要的其他列,并且引用了不应影响结果的表(这些表可能至少有一行,但是这些表中没有数据引用,通常不需要多行)。

Thanks for all the assistance but I went back to basics. 感谢您提供的所有帮助,但我又回到了基础知识。 I cut the joined tables out and went to the basic four columns that I needed without the translation data. 我将联接表切出,转到没有翻译数据所需的基本四列。 Once I did that I saw that the table only created duplicate entries with a 1900 date field so I simply used a WHERE clause to strip out the extra entry. 这样做之后,我看到该表仅创建具有1900 date字段的重复条目,因此我仅使用WHERE子句删除了多余的条目。 I was really interested in Clockwork-Muse's method but I kept receiving a syntax error that didn't make sense and once I saw the issue I was having it was less code to strip what I needed. 我对Clockwork-Muse的方法非常感兴趣,但是我一直收到没有意义的语法错误,一旦我看到了这个问题,我得到的是更少的剥离我所需内容的代码。 Thank you again for the support and information. 再次感谢您的支持和信息。

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

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