簡體   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