从包含最大值的行中选择不同的列

时间:2014-02-28 16:08:42

标签: sql sql-server tsql

我的查询如下:

  SELECT     [ScriptName]
        ,[BranchName]
        ,AVG([XMLColumn].value('count(//data)', 'int'))
        ,MIN([XMLColumn].value('count(//data)', 'int'))
        ,MAX([XMLColumn].value('count(//data)', 'int'))
  FROM temp
  GROUP BY [BranchName], [ScriptName]

我正在查询的表格结构如下:

ScriptName | BranchName | XMLLog | Developer | Revision

目前,我的结果查询产生如下输出:

ScriptName | BranchName | Average | Min | MAX
-------------------------------------------------
Script 1   | trunk      |  80     | 11  | 120
Script 2   | branch1    |  15     | 11  | 21

我想在结果表中添加两列:包含最小值的行中的开发人员和包含最大值的行中的开发人员。这将导致查询的输出如下所示:

ScriptName | BranchName | Average | Min | MAX  | DeveloperWhoCausedMinimum | DeveloperWhoCausedMaximum
-----------------------------------------------------------------------------------------------------------------
Script 1   | trunk      |  80     | 11  | 120  |      me                   |     The Boss
Script 2   | branch1    |  15     | 11  | 21   |      me                   |     The Boss

我不知道从哪里开始。谢谢!

1 个答案:

答案 0 :(得分:1)

以下使用窗口函数来计算三个值。然后它选择具有最大值的整行:

select t.*, avgval, minval, maxval
from (select t.*,
             avg([XMLColumn].value('count(//data)', 'int') over
                 (partition by BranchName, ScriptName) as avgval,
             min([XMLColumn].value('count(//data)', 'int') over
                 (partition by BranchName, ScriptName) as minval,
             max([XMLColumn].value('count(//data)', 'int') over
                 (partition by BranchName, ScriptName) as maxval
      from temp t
     ) t
where [XMLColumn].value('count(//data)', 'int') = maxval;

注意:如果多行具有最大值,您将获得多行。如果您只想要一个,请改用row_number()

编辑:

哦,你把问题从两个不同的行改为一列而不是一列的两行。

使用相同的想法但使用聚合:

select BranchName, ScriptName, minval, avgval, maxval,
       avg([XMLColumn].value('count(//data)', 'int') as avgval,
       min([XMLColumn].value('count(//data)', 'int') as minval,
       max([XMLColumn].value('count(//data)', 'int') as maxval,
       max(case when seqnum = 1 then Developer end) as minDeveloper,
       max(case when seqnum = cnt then Developer end) as maxDeveloper
from (select t.*,
             row_number() over (partition by BranchName, ScriptName
                                order by [XMLColumn].value('count(//data)', 'int')
                               ) as seqnum,
             count(*) over (partition by BranchName, ScriptName) as cnt
      from temp t
     ) t
group by BranchName, ScriptName;