2016-09-02 2 views
0

У меня есть следующий запрос, который вытягивает максимальные и средние значения процессора и памяти для каждого сервера.Count Записи между значениями

SELECT 
    Nodes.Caption, Max(CPULoad.MaxLoad) as CPUMax, 
    AVG(CPULoad.AvgLoad) as CPUAvg, 
    Round(Max(CPULoad.MaxMemoryUsed/CPULoad.TotalMemory * 100),2) as MemMax, 
    Round(AVG(CPULoad.AvgPercentMemoryUsed),2) as MEMAvg 
FROM    
    Nodes 
INNER JOIN 
    CPULoad ON Nodes.NodeID = CPULoad.NodeID 
WHERE 
    Datetime >= DATEADD(MONTH,datediff(MONTH,0,getdate())-1,0)   
    AND Datetime < DATEADD(MONTH,datediff(MONTH,0,getdate()),0) 

GROUP BY Nodes.Caption

Теперь нужно выяснить следующее.

Подсчет каждого значения (cpumax, cpuavg, memmax, memavg), которые находятся между следующими диапазонами:

  1. '> = 0 < = 10'
  2. '> = 10 < = 20'
  3. '> = 20 = < 30'
  4. '> = 30 < = 40'
  5. '> = 40 < = 50'

Я пытался что-то вроде SUM(case when Max(CPULoad.MaxLoad) < 10 then 1 else 0 end), но я получаю сообщение об ошибке

Невозможно использовать агрегат или подзапрос в выражении используется для группы по списку в предложения GROUP BY

I попытался добавить как весь оператор, так и только max(cpuload.maxload) в GROUP BY, но ему это не нравится.

Наконец, мне нужно сгруппировать каждый из серверов по определенным диапазонам. То есть все серверы, которые имеют cpumax от 0 до 10 вместе с их соответствующим значением.

+0

Что RDBMS вы используете? Совокупные значения над некоторыми разделами данных могут быть достигнуты с помощью функций Windows, например, в [PostgreSQL] (https://www.postgresql.org/docs/current/static/tutorial-window.html). –

ответ

0

Сделайте существующий запрос производной таблицей, сделав ее подзапросом с псевдонимом. Затем используйте конструкцию случая. Вот общая идея. Вы можете заполнить детали.

select case when 1 = 1 then 'true' else 'false' end alias1 
from 
(your query goes here) alias2 
1

попробуйте ниже запрос .. еще не тестировал :)

DECLARE @table TABLE(MinVal INT,MaxVal INT) 
INSERT INTO @table (MinVal,MaxVal) 
VALUES (0,10),(10,20),(20,30),(30,40),(40,50) 

WITH cte_1 
as 
    (SELECT 
    Nodes.Caption, Max(CPULoad.MaxLoad) as CPUMax, 
    AVG(CPULoad.AvgLoad) as CPUAvg, 
    Round(Max(CPULoad.MaxMemoryUsed/CPULoad.TotalMemory * 100),2) as MemMax, 
    Round(AVG(CPULoad.AvgPercentMemoryUsed),2) as MEMAvg 

    FROM    
    Nodes INNER JOIN 
      CPULoad ON Nodes.NodeID = CPULoad.NodeID 

    WHERE 
    Datetime >= DATEADD(MONTH,datediff(MONTH,0,getdate())-1,0)  AND 
    Datetime < DATEADD(MONTH,datediff(MONTH,0,getdate()),0) 

    GROUP BY Nodes.Caption) 
    SELECT *, ISNULL('>= '+CAST(t.MinVal as VARCHAR(50))+' < '+CAST(t.MaxVal as VARCHAR(50)),'') CPUMaxInterval 
      , ISNULL('>= '+CAST(t1.MinVal as VARCHAR(50))+' < '+CAST(t1.MaxVal as VARCHAR(50)),'') CPUAvgInterval 
      , ISNULL('>= '+CAST(t2.MinVal as VARCHAR(50))+' < '+CAST(t2.MaxVal as VARCHAR(50)),'') MemMaxInterval 
      , ISNULL('>= '+CAST(t3.MinVal as VARCHAR(50))+' < '+CAST(t3.MaxVal as VARCHAR(50)),'') MEMAvgInterval 
    FROM cte_1 ct 
    LEFT JOIN @table t on ct.CPUMax >= t.MinVal and ct.CPUMax <t.MaxVal 
     LEFT JOIN @table t1 on ct.CPUAvg >= t.MinVal and ct.CPUAvg <t.MaxVal 
     LEFT JOIN @table t2 on ct.MemMax >= t.MinVal and ct.MemMax <t.MaxVal 
     LEFT JOIN @table t3 on ct.MEMAvg >= t.MinVal and ct.MEMAvg <t.MaxVal 
Смежные вопросы