在时间范围内选择唯一/不同的条目

时间:2017-01-11 16:41:22

标签: sql sql-server sql-server-2012

这是我的DC中VM的表格布局。我们每小时收集指标,但希望防止两次投票的结果,然后在给定的小时内结束双重信息。

以下是我的表

VM_Name              NUM_VCPU   POWER_STATE MEMORY_MB   IMPORTEDTIMESTAMP
-------------------------------------------------------------------------
FERNANDO TEST 2012      4           1         16384      2017-01-10 10:13:42.353
FERNANDO TEST 2012 R2   4           0          8192      2017-01-10 10:13:42.353

之前是我用来获取上述信息的查询

SELECT Count([VM_NAME]) as Num_VM
      ,sum([NUM_VCPU]) as SUM_NUM_VCPU
      ,SUM([MEMORY_MB]) as SUM_MEM_MB
      ,SUM([MEMORY_MB])/1024 as SUM_MEM_GB
      ,dateadd(hour, datediff(hour, 0, IMPORTEDTIMESTAMP), 0) as IMPORTEDTIMESTAMPROUND       
  FROM VM_DATA
  Where POWER_STATE = 1
  group by dateadd(hour, datediff(hour, 0, IMPORTEDTIMESTAMP), 0)

我得到了

 Num_VM SUM_NUM_VCPU    SUM_MEM_MB  SUM_MEM_GB  IMPORTEDTIMESTAMPROUND  
---------------------------------------------------------------------------      
    2         |4        |24576       |24        |2017-01-10 16:00:00.000     
    1         |2        |12288       |12        |2017-01-11 02:00:00.000    
    1         |2        |12288       |12        |2017-01-11 03:00:00.000

正如您在下午4点(2017-01-10 16:00:00.000)所看到的那样,有一个测试双重调查,现在我已经将指标加倍了。我如何调整我的查询以获得不同的值,我认为必须做一个子查询但不确定在哪里。

编辑以进一步澄清。

所以在2017-01-10 16:00:00.000我进行了两次调查,现在我有重复的记录。我需要选择不同的vm_name和不同的timesstmap来删除重复项,然后计算所有的vms,总结cpu和内存并按时间分组它们

3 个答案:

答案 0 :(得分:0)

最简单的解决方案是使用avg()

SELECT Count([VM_NAME]) as Num_VM,
       sum([NUM_VCPU]) as SUM_NUM_VCPU,
       SUM([MEMORY_MB]) as SUM_MEM_MB,
       SUM([MEMORY_MB])/1024 as SUM_MEM_GB,
       dateadd(hour, datediff(hour, 0, IMPORTEDTIMESTAMP), 0) as IMPORTEDTIMESTAMPROUND       
FROM VM_DATA
Where POWER_STATE = 1
GROUP BY dateadd(hour, datediff(hour, 0, IMPORTEDTIMESTAMP), 0);

否则。 。 。只需使用row_number()。似乎没有必要聚合:

select d.*
from (select d.*,
             (partition by year(IMPORTEDTIMESTAMP), month(IMPORTEDTIMESTAMP), day(IMPORTEDTIMESTAMP), datepart(hour, IMPORTEDTIMESTAMP)
              order by IMPORTEDTIMESTAMP
             ) as seqnum
      from vm_data d
     ) d
where seqnum = 1;

答案 1 :(得分:0)

所以问题是你的记录实际上不是重复的,但是因为时间戳舍入而出现了吗?使用DISTINCT时会发生什么?我假设它在您对时间戳进行任何舍入之前考虑列,这将返回相同的结果。我认为您需要将舍入日期转换为varchar,然后可能将distinct识别为实际副本。

请参阅:Returning Distinct Dates

SELECT DISTINCT Count([VM_NAME]) as Num_VM
  ,sum([NUM_VCPU]) as SUM_NUM_VCPU
  ,SUM([MEMORY_MB]) as SUM_MEM_MB
  ,SUM([MEMORY_MB])/1024 as SUM_MEM_GB
  ,CONVERT(char(10), dateadd(hour, datediff(hour, 0, IMPORTEDTIMESTAMP), 0), 126) as IMPORTEDTIMESTAMPROUND       
FROM VM_DATA
Where POWER_STATE = 1
group by CONVERT(char(10), dateadd(hour, datediff(hour, 0, IMPORTEDTIMESTAMP), 0), 126)

答案 2 :(得分:0)

case when (count(dateadd(hour, datediff(hour, 0, IMPORTEDTIMESTAMP), 0))-count(Distinct(VM_Name))) = 0 then SUM(NUM_VCPU)
    else SUM(NUM_VCPU)/(count(dateadd(hour, datediff(hour, 0, IMPORTEDTIMESTAMP), 0))/count(Distinct(VM_Name))) end as SUM_VCPU 

我不得不清理它,但我想出的是有效的。它检查VM_Names的不同计数的数量应该与时间戳的计数匹配。如果我有更多的时间戳而不是不同的名称,那么我知道我在给定的时间范围内有多个条目。我对总和进行了一些除法以获得正确的数字

我不知道是否有更好的方法来实现这一目标,但它确实有效。