SQL平均结果

时间:2012-04-09 14:24:18

标签: sql sql-server select

我有以下SQL查询

SELECT TOP 10000 AVG(DailyNodeAvailability.Availability) AS AVERAGE_of_Availability
FROM Nodes 
INNER JOIN DailyNodeAvailability 
    ON (Nodes.NodeID = DailyNodeAvailability.NodeID)
WHERE 
( DateTime > (GetDate()-7) )
 AND  
(
  (
  (Nodes.Caption LIKE '%server1%') OR 
  (Nodes.Caption LIKE '%server2%') OR 
  (Nodes.Caption LIKE '%server3%') 
  )
)

它给了我3台服务器的平均可用性报告。但我想要最少的可用性。例如。

Server1 = 100%
Server2 = 97%
Server3 = 88%

我希望SQL查询结果中至少有一个是Server3 = 88%(非平均值)

如何修改现有查询以使其有效?

有混乱所以,附上结果的照片。它给了我单一的结果,但平均而且我不想要平均我在结果中需要最少的结果值,例如。

enter image description here

3 个答案:

答案 0 :(得分:2)

SELECT MIN(AVERAGE_of_Availability)
FROM
(
SELECT AVG(DailyNodeAvailability.Availability) AS AVERAGE_of_Availability
FROM Nodes 
INNER JOIN DailyNodeAvailability 
    ON (Nodes.NodeID = DailyNodeAvailability.NodeID)
WHERE 
( DateTime > (GetDate()-7) )
 AND  
(
  (
  (Nodes.Caption LIKE '%server1%') OR 
  (Nodes.Caption LIKE '%server2%') OR 
  (Nodes.Caption LIKE '%server3%') 
  )
)
group by Nodes.Caption
) AvgAvailability

这将为您提供最低限度,但不会告诉您显示的服务器。要获取服务器名称(Nodes.Caption),我们必须做更多。因为它不在原始查询中,所以我不包括那部分,否则会使它变得更复杂。

答案 1 :(得分:2)

您的基本查询应写为:

SELECT N.Caption AS Server, AVG(A.Availability) AS Avg_Availability
  FROM Nodes AS N
  JOIN DailyNodeAvailability AS A ON (N.NodeID = A.NodeID)
 WHERE DateTime > (GetDate()-7)
   AND (N.Caption LIKE '%server1%' OR
        N.Caption LIKE '%server2%' OR
        N.Caption LIKE '%server3%'
       )
 GROUP BY N.Caption

这将为您提供一个列表,其中列出了上周每个服务器名称和该服务器的平均可用性。

要获取具有最低平均可用性及其平均可用性的服务器名称,您必须将该查询视为较大查询的一部分。在标准SQL中有两种方法可以做到这一点:啰嗦和普遍可用,简洁但不太广泛。

这种冗长的方式最终会将该查询作为子查询写出几次(因此,在开发查询时,在继续执行更复杂的查询之前,确保第一个查询正确并经过测试至关重要):

SELECT m.server, m.avg_availability
  FROM (SELECT N.Caption AS Server, AVG(A.Availability) AS Avg_Availability
          FROM Nodes AS N
          JOIN DailyNodeAvailability AS A ON (N.NodeID = A.NodeID)
         WHERE DateTime > (GetDate()-7)
           AND (N.Caption LIKE '%server1%' OR
                N.Caption LIKE '%server2%' OR
                N.Caption LIKE '%server3%'
               )
         GROUP BY N.Caption
       ) AS m
  JOIN (SELECT MIN(y.avg_availability) AS min_availability
          FROM (SELECT N.Caption AS Server, AVG(A.Availability) AS Avg_Availability
                  FROM Nodes AS N
                  JOIN DailyNodeAvailability AS A ON (N.NodeID = A.NodeID)
                 WHERE DateTime > (GetDate()-7)
                   AND (N.Caption LIKE '%server1%' OR
                        N.Caption LIKE '%server2%' OR
                        N.Caption LIKE '%server3%'
                       )
                 GROUP BY N.Caption
               ) AS Y
       ) AS x
    ON x.min_availability = m.avg_availability

这种简洁的方法使用公用表表达式,即WITH子句:

WITH AvgAvailability AS
    (
    SELECT N.Caption AS Server, AVG(A.Availability) AS Avg_Availability
      FROM Nodes AS N
      JOIN DailyNodeAvailability AS A ON (N.NodeID = A.NodeID)
     WHERE DateTime > (GetDate()-7)
       AND (N.Caption LIKE '%server1%' OR
            N.Caption LIKE '%server2%' OR
            N.Caption LIKE '%server3%'
           )
     GROUP BY N.Caption
    )
SELECT A.Server, A.Avg_Availabilty
  FROM AvgAvailability AS A
  JOIN (SELECT MIN(Avg_Availability) AS Min_Availability
          FROM AvgAvailability
       ) AS M
    ON A.Avg_Availability = M.Min_Availability

(语法未经测试。)我不确定MS SQL Server中是否有可用的简洁选项。

答案 2 :(得分:2)

您可以在SQL Server中更紧凑地执行此操作:

SELECT TOP (1) WITH TIES
  N.Caption AS Server,
  AVG(A.Availability) AS Avg_Availability
FROM Nodes AS N
JOIN DailyNodeAvailability AS A
ON (N.NodeID = A.NodeID)
WHERE DateTime > (GetDate()-7)
AND N.Caption LIKE '%server[123]%'
GROUP BY N.Caption
ORDER BY AVG(A.Availability)