在每条记录上调用SQL存储过程,需要基于集合的解决方案

时间:2011-12-27 23:16:46

标签: sql sql-server-2005 greatest-n-per-group

我从这篇文章中描述的那个创建了一个游标:SQL - Call Stored Procedure for each record

但我真正想要的是基于集合的解决方案。我有两个表,Tickets和WorkLogs。 每张票可以有多个工作日志,我只想要每张票最新。

 SELECT WorkLog.WorkLogDate, WorkLog.TextEntry, Ticket.ID,
             Ticket.Summary, Ticket.Requester, Ticket.Status, Ticket.Priority, 
             Ticket.AssignedTo, Ticket.DateResolved, Ticket.TimeSpent
 FROM Ticket INNER JOIN WorkLog ON Ticket.ID = WorkLog.TicketIDRef

如果我能以某种方式SELECT TOP (1) _WorkLog_ FROM WorkLog ORDER BY WorkLogID DESC获得Tickets中的每个Ticket.ID,我会得到我正在寻找的集合。我使用CROSS APPLY看到了一些类似的解决方案,但我不确定我需要应用什么功能。

非常感谢任何让我的大脑脱离OO装备的帮助。

2 个答案:

答案 0 :(得分:1)

有几种方法可以做到。

1)NOT EXISTS

SELECT WorkLog.WorkLogDate, WorkLog.TextEntry, Ticket.ID,
             Ticket.Summary, Ticket.Requester, Ticket.Status, Ticket.Priority, 
             Ticket.AssignedTo, Ticket.DateResolved, Ticket.TimeSpent
 FROM Ticket INNER JOIN WorkLog ON Ticket.ID = WorkLog.TicketIDRef
WHERE not exists (SELECT 1 FROM WorkLog w2 WHERE w2.TicketIDRef = Ticket.ID AND w2.WorkLogDate > WorkLog.WorkLogDate)

2)子选择

  SELECT 
       (
        SELECT TOP 1 
          WorkLog.TextEntry 
        FROM 
          WorkLog 
        WHERE 
          Ticket.ID = WorkLog.TicketIDRef
        ORDER BY
          WorkLog.WorkLogDate DESC
       ) as TextEntry, 
       Ticket.ID,
       Ticket.Summary, Ticket.Requester, Ticket.Status, Ticket.Priority, 
       Ticket.AssignedTo, Ticket.DateResolved, Ticket.TimeSpent
 FROM Ticket

3)加入

SELECT WorkLog.WorkLogDate, WorkLog.TextEntry, Ticket.ID,
             Ticket.Summary, Ticket.Requester, Ticket.Status, Ticket.Priority, 
             Ticket.AssignedTo, Ticket.DateResolved, Ticket.TimeSpent
 FROM Ticket 
        INNER JOIN WorkLog ON Ticket.ID = WorkLog.TicketIDRef
        INNER JOIN (
                     SELECT 
                       max(WorkLogDate), 
                       TicketIDRef
                     FROM
                       WorkLog w2
                     GROUP BY
                       TicketIDRef
                    ) wMax ON
          WorkLog.WorkLogDate = wMax.WorkLogDate AND
          wMax.TicketIDRef = WorkLog.TicketIDRef

答案 1 :(得分:0)

您正在寻找的是使用row_number函数

SELECT ROW_NUMBER() OVER (PARTITION BY Ticket.ID ORDER BY WorkLog.ID DESC) rowNumber,
       WorkLog.WorkLogDate, WorkLog.TextEntry, Ticket.ID,
       Ticket.Summary, Ticket.Requester, Ticket.Status, Ticket.Priority, 
       Ticket.AssignedTo, Ticket.DateResolved, Ticket.TimeSpent
FROM Ticket 
     INNER JOIN WorkLog ON Ticket.ID = WorkLog.TicketIDRef
WHERE rowNumber  1