【问题标题】:Select row with max date from duplicate results从重复结果中选择具有最大日期的行
【发布时间】:2012-05-01 05:38:16
【问题描述】:

注意:我正在使用 SQL 2000。

我想通过为此加入执行类似的操作来选择 t2.JobCompletionTime 的 MAX 日期的行,但我知道这不是正确的代码/语法,因为它不起作用......但我希望它是明确我想要做什么。

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

【问题讨论】:

  • 我个人会考虑添加几个表格来保存您的Job StatusError Description 描述。此外,在引用主表和连接表时,我不会使用子查询,而只是为每个主查询 WHERE 子句的一部分创建 WHERE 子句。这将使查询更具可读性。
  • 从你的问题中不清楚你在追求什么。您能否详细说明以下声明:“如果以下为真,我将 t2.JobCompletionTime 设置为 NULL,但我仍想选择 MAX t2.JobCompletionTime...”。
  • 我编辑了上面的问题,希望能提供更多的清晰度。

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


【解决方案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'

希望这会有所帮助。

【讨论】:

  • PS:我已将t3.VolumeName = 'C:\' 更改为...= 'C:',因为它似乎混淆了语法高亮,您可能需要将它改回原来的样子!
【解决方案2】:

您发布了太多不相关的 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 中为您提供 first 匹配行(最新的,因为我们对行进行了排序)

【讨论】:

  • 运行此代码时出现错误:ORDER BY 子句在视图、内联函数、派生表和子查询中无效,除非还指定了 TOP。
  • 我将其更改为: LEFT OUTER JOIN ( SELECT * FROM ( SELECT TOP 100 PERCENT * FROM DSM_StandardProcedureActivityView 但是现在我收到一条错误消息:关键字 'GROUP' 附近的语法不正确。' 附近的语法不正确t3'。
  • 哦,对不起 - 我可以发誓我看到了一个 mysql 标签。这仅适用于 mysql :(
【解决方案3】:

一个名为 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 行;因此在连接子句中添加了额外的子句。

【讨论】:

  • 感谢您提供此解决方案,但我正在使用 SQL 2000 并且 ROW_NUMBER() 是 SQL 2005 以后添加的函数。
  • 我的错;我没有看到 sql-server-2000 标签。如果这对能够使用 ROW_NUMBER() 的其他人有用,我会留下答案。
猜你喜欢
  • 2016-12-22
  • 1970-01-01
  • 1970-01-01
  • 2019-01-23
  • 2013-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-04
相关资源
最近更新 更多