如何将列添加到聚合函数中

时间:2014-04-18 12:30:27

标签: sql aggregate

这是我的问题:

SELECT 
   dateTime, 
   AVG([timeTaken]) as avgtime, 
   MAX([timeTaken]) as maxtime, 
   COUNT(*) totalcalls
FROM 
   [Logs]
WHERE 
   csUriStem = '/REST/Issues/Issues.svc/' AND 
   [dateTime] > DATEADD(MINUTE, -15, GETUTCDATE()) AND
   (csUserAgent != 'Fiddler' OR csUserAgent IS NULL)

执行时出现此错误:

  

Msg 8120,Level 16,State 1,Line 2
  列'Logs.dateTime'在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。

我理解为什么,但我的问题是,如何将关联的DateTime与相应的[MAX([timeTaken]) as maxtime]相关联?

4 个答案:

答案 0 :(得分:1)

好的,如果AVG列表中还有其他字段,那么MAXCOUNTGROUP BY等汇总函数将需要某种SELECT 。这就是他们如何知道要操作的子集。所以,你需要做的就是 run ,这是这样的:

SELECT dateTime,
    AVG([timeTaken]) as avgtime,
    MAX([timeTaken]) as maxtime,
    COUNT(*) totalcalls
FROM [Logs]
WHERE 
    csUriStem = '/REST/Issues/Issues.svc/' AND 
    [dateTime] > DATEADD(MINUTE, -15, GETUTCDATE()) AND
    (csUserAgent != 'Fiddler' OR csUserAgent IS NULL)
GROUP BY dateTime

但是,或者可能是您想要的。这将在AVG的每个分组上执行MAXCOUNTdateTime over

然而,dateTime的这种分组可能是不合逻辑的;你可能想要这样的东西:

SELECT CONVERT(VARCHAR(8), dateTime, 101) AS groupDate,
    AVG([timeTaken]) as avgtime,
    MAX([timeTaken]) as maxtime,
    COUNT(*) totalcalls
FROM [Logs]
WHERE 
    csUriStem = '/REST/Issues/Issues.svc/' AND 
    [dateTime] > DATEADD(MINUTE, -15, GETUTCDATE()) AND
    (csUserAgent != 'Fiddler' OR csUserAgent IS NULL)
GROUP BY CONVERT(VARCHAR(8), dateTime, 101)

这将按mm/dd/yy格式化该分组日期。

要进一步考虑使用聚合函数实际进行的操作,如果没有有任何其他字段:

SELECT AVG([timeTaken]) as avgtime,
    MAX([timeTaken]) as maxtime,
    COUNT(*) totalcalls
FROM [Logs]
WHERE 
    csUriStem = '/REST/Issues/Issues.svc/' AND 
    [dateTime] > DATEADD(MINUTE, -15, GETUTCDATE()) AND
    (csUserAgent != 'Fiddler' OR csUserAgent IS NULL)

它仍然在组上运行。 恰好是整个结果集。

答案 1 :(得分:0)

您需要将其包含在group by子句

像这样。

SELECT 
    dateTime, 
    AVG([timeTaken]) as avgtime, 
    MAX([timeTaken]) as maxtime, 
    COUNT(*) totalcalls
  FROM 
    [Logs]
  WHERE
    csUriStem = '/REST/Issues/Issues.svc/' AND 
    [dateTime] > DATEADD(MINUTE, -15, GETUTCDATE()) AND
    (csUserAgent != 'Fiddler' OR csUserAgent IS NULL)
  GROUP BY
    dateTime;

请注意,如果您需要有关平均值和最大值的信息,则需要将查询拆分为两个单独的查询。然后合并它们。

答案 2 :(得分:0)

您需要在组中包含dateTime列,或者根据您的要求选择avg / max / min

 SELECT dateTime, AVG([timeTaken]) as avgtime, MAX([timeTaken]) as maxtime, COUNT(*) totalcalls
      FROM [Logs]
      WHERE 
        csUriStem = '/REST/Issues/Issues.svc/' AND 
        [dateTime] > DATEADD(MINUTE, -15, GETUTCDATE()) AND
        (csUserAgent != 'Fiddler' OR csUserAgent IS NULL)
      GROUP BY dateTime

答案 3 :(得分:0)

如果您只想要一行,并且希望它的最大值为DateTime,那么您可以使用聚合order bytop执行此操作:

SELECT TOP 1 dateTime, AVG([timeTaken]) as avgtime, 
       MAX([timeTaken]) as maxtime, COUNT(*) totalcalls
FROM [Logs]
WHERE csUriStem = '/REST/Issues/Issues.svc/' AND 
      [dateTime] > DATEADD(MINUTE, -15, GETUTCDATE()) AND
      (csUserAgent != 'Fiddler' OR csUserAgent IS NULL)
GROUP BY dateTime
order by dateTime desc;