从重复结果中选择具有最大日期的行

时间:2012-05-01 05:38:16

标签: sql sql-server tsql sql-server-2000

注意:我正在使用SQL 2000。

我想为t2.JobCompletionTime选择具有MAX日期的行,为此Join执行类似的操作,但我知道这不是正确的代码/语法,因为它不起作用...但我希望它是清除我想要做的事情。

LEFT OUTER JOIN (
  SELECT *
  FROM DSM_StandardProcedureActivityView
  WHERE
  ( (PackageName = 'Adobe Acrobat 10'  AND PackageVersion = '-1.0') AND
    (MAX (JobCompletionTime))
  )
) t2 ON t1.UUID = t2.UUID

我现在正在使用的完整SQL代码是:

SELECT 
t1.Business,
t1.[Sub-Business],
t1.Pole,
t1.DomainManager,
t1.ScalabilityServer,
t1.Location,
t1.Country,
t1.Name,
t3.VolumeName,
t3.VolumeFreeInMB,
t3.VolumeSizeInMB,
FROM (
  SELECT *
  FROM DSM_StandardGroupMembersView
  WHERE 
  (  GroupName = 'Adobe Acrobat'
  )
) t1
LEFT OUTER JOIN (
  SELECT *
  FROM DSM_StandardProcedureActivityView
  WHERE
  ( (PackageName = 'Adobe Acrobat 10'  AND PackageVersion = '-1.0')
  )
) t2 ON t1.UUID = t2.UUID
LEFT OUTER JOIN (
  SELECT *
  FROM DSM_StandardHardwareDiskUsageView
  WHERE VolumeName = 'C:\'
) t3 ON t1.Name = t3.Name
ORDER BY t1.Business, t1.[Sub-Business], t1.Pole, t1.DomainManager, t1.ScalabilityServer, t1.Country, t1.Location, [Job Status], t1.Name

3 个答案:

答案 0 :(得分:1)

你已经发布了太多不相关的SQL供我浏览,所以我只是修复你的摘录:

LEFT OUTER JOIN (
  SELECT * FROM (
    SELECT *
    FROM DSM_StandardProcedureActivityView
    WHERE PackageName = 'Adobe Acrobat 10'
    AND PackageVersion = '-1.0'
    ORDER BY JobCompletionTime DESC) x
   ) y
   GROUP BY PackageName, PackageVersion
) t2 ON t1.UUID = t2.UUID

这里发生的是内部查询首先获取按最新JobCompletionTime排序的行,下一级查询使用匹配列上的group by,在mysql中,它为您提供第一个匹配行(最新的,因为我们排序了行)

答案 1 :(得分:1)

名为ROW_NUMBER()的排名函数可以帮助您

LEFT OUTER JOIN (
    SELECT 
        *, 
        rowNumber = ROW_NUMBER() OVER (ORDER BY JobCompletionTime DESC)
    FROM DSM_StandardProcedureActivityView
    WHERE PackageName = 'Adobe Acrobat 10'
    AND PackageVersion = '-1.0'
) t2 ON t1.UUID = t2.UUID AND rowNumber = 1

按JobCompletionTime(降序)排序应将最高值设为行号1;因此,extra子句被添加到join子句中。

答案 2 :(得分:1)

逐步完成这一步,以便更清楚地说明我在这里可能会产生解释错误......

第1步:稍微美化您的查询+省略ORDER BY,因为您可以稍后再轻松添加该查询

SELECT t1.Business,
       t1.[Sub-Business],
       t1.Pole,
       t1.DomainManager,
       t1.ScalabilityServer,
       t1.Location,
       t1.Country,
       t1.Name,
       t3.VolumeName,
       t3.VolumeFreeInMB,
       t3.VolumeSizeInMB

  FROM DSM_StandardGroupMembersView  t1

  LEFT OUTER JOIN DSM_StandardProcedureActivityView t2
               ON t2.PackageName = 'Adobe Acrobat 10'  
              AND t2.PackageVersion = '-1.0'
              AND t2.UUID = t1.UUID

  LEFT OUTER JOIN DSM_StandardHardwareDiskUsageView t3
               ON t3.VolumeName = 'C:'
              AND t3.Name = t1.Name

 WHERE t1.GroupName = 'Adobe Acrobat'

我理解你的问题的方法是你想要将DSM_StandardProcedureActivityView t2中的记录限制为那些代表最新情况的记录(基于t2.JobCompletionTime字段)。对 ?现在我们要先对这个进行分组,然后加入那些匹配的(通过UUID),或者我们反过来考虑这个,首先让列表限制为所需的UUID,然后去除所有那些 有一个更新的版本。 因为你在SQL2000上我会建议后者,因为我不确定查询优化器是否能够优化前者。 (随意测试=)

这看起来像这样:

SELECT t1.Business,
       t1.[Sub-Business],
       t1.Pole,
       t1.DomainManager,
       t1.ScalabilityServer,
       t1.Location,
       t1.Country,
       t1.Name,
       t3.VolumeName,
       t3.VolumeFreeInMB,
       t3.VolumeSizeInMB

  FROM DSM_StandardGroupMembersView  t1

  LEFT OUTER JOIN DSM_StandardProcedureActivityView t2
               ON t2.PackageName = 'Adobe Acrobat 10'  
              AND t2.PackageVersion = '-1.0'
              AND t2.UUID = t1.UUID
              -- limit to latest records only!
              AND NOT EXISTS ( SELECT *
                                 FROM DSM_StandardProcedureActivityView t2_newer
                                WHERE t2_newer.UUID = t2.UUID
                                  AND t2_newer.JobCompletionTime > t2.JobCompletionTime )

  LEFT OUTER JOIN DSM_StandardHardwareDiskUsageView t3
               ON t3.VolumeName = 'C:'
              AND t3.Name = t1.Name

 WHERE t1.GroupName = 'Adobe Acrobat'

希望这有帮助。