SUM一个具有不同分组记录的字段

时间:2015-11-14 12:25:38

标签: sql sql-server sql-server-2008

我有一个非常棘手的SQL问题,我无法深究。我有一个SQL视图,其中列出了服务器及其与电源板的电源连接(大约44,500个连接到大约8,000个电源板。我现在需要做的是创建一个视图,显示每个电源板的单个条目及其总负载(瓦特) 。

这是我工作的表格的一个简短示例:

POWERSTRIP_VOB_ID                       DEVICE_VOB_ID                           WATTS
5FA38587-FA3E-4BF0-B87C-B782B0FD9284    988BD4A4-CAC7-4CC9-B1F8-274D75C48796    17
5FA38587-FA3E-4BF0-B87C-B782B0FD9284    67174BE5-9065-4131-8817-EB584F940A39    17
5FA38587-FA3E-4BF0-B87C-B782B0FD9284    44713911-F1D8-45E6-9FFA-DCD29F0A5EDA    1164
5FA38587-FA3E-4BF0-B87C-B782B0FD9284    D4495808-AE45-4F8E-ADB0-A97C5F79FD70    17
5FA38587-FA3E-4BF0-B87C-B782B0FD9284    A9B17915-85F2-4FE1-915A-044312177845    7481
5FA38587-FA3E-4BF0-B87C-B782B0FD9284    5AC7AA8A-8A56-4E09-A607-98985782B32B    1746
5FA38587-FA3E-4BF0-B87C-B782B0FD9284    A9B17915-85F2-4FE1-915A-044312177845    7481
5FA38587-FA3E-4BF0-B87C-B782B0FD9284    A9B17915-85F2-4FE1-915A-044312177845    7481

如您所见,所有行都具有相同的POWERSTRIP_VOB_ID。在此示例中,所有服务器至少有一个与此powerstrip的连接。您还会注意到,以A9B17915开头的设备有三个连接到电源板的连接。

如果我使用DISTINCTGROUP BY POWERSTRIP_VOB_ID并使用瓦特上的SUM,我会得到25,404的结果。我需要做的是基本上忽略任何重复连接,以便查询仅为powerstrip对服务器求和一次。

在这个例子中,我将寻找总和:

POWERSTRIP_VOB_ID                       DEVICE_VOB_ID                           WATTS
5FA38587-FA3E-4BF0-B87C-B782B0FD9284    988BD4A4-CAC7-4CC9-B1F8-274D75C48796    17
5FA38587-FA3E-4BF0-B87C-B782B0FD9284    67174BE5-9065-4131-8817-EB584F940A39    17
5FA38587-FA3E-4BF0-B87C-B782B0FD9284    44713911-F1D8-45E6-9FFA-DCD29F0A5EDA    1164
5FA38587-FA3E-4BF0-B87C-B782B0FD9284    D4495808-AE45-4F8E-ADB0-A97C5F79FD70    17
5FA38587-FA3E-4BF0-B87C-B782B0FD9284    A9B17915-85F2-4FE1-915A-044312177845    7481
5FA38587-FA3E-4BF0-B87C-B782B0FD9284    5AC7AA8A-8A56-4E09-A607-98985782B32B    1746

这应该会在视图中产生1条记录,如:

POWERSTRIP_VOB_ID                       WATTS
5FA38587-FA3E-4BF0-B87C-B782B0FD9284    10442

希望我已经解释得那么好了。

我已经使用GROUP BYDISTINCTSUM(DISTINCT)进行了游戏,似乎无法获得我需要的输出。

真的很感激任何帮助。

非常感谢

西蒙

2 个答案:

答案 0 :(得分:4)

我认为这就是你所需要的:

SELECT POWERSTRIP_VOB_ID, SUM(WATTS)
FROM (
        SELECT DISTINCT POWERSTRIP_VOB_ID, DEVICE_VOB_ID, WATTS
        FROM   myTable
)
GROUP BY POWERSTRIP_VOB_ID;

内部查询排除重复项,外部查询生成总和。

根据您的描述,我发现2条记录不可能具有相同的POWERSTRIP_VOB_ID和DEVICE_VOB_ID值,但WATTS不同。我想这可能表明数据库不一致。无论如何,如果发生这种情况,上述查询将对这两个值求和。

答案 1 :(得分:0)

作为已发布答案的替代方案,您也可以尝试:

SELECT POWERSTRIP_VOB_ID, SUM(WATTS)
FROM (
    SELECT POWERSTRIP_VOB_ID, DEVICE_VOB_ID, WATTS
    FROM   myTable
    GROUP BY POWERSTRIP_VOB_ID, DEVICE_VOB_ID, WATTS
)
GROUP BY POWERSTRIP_VOB_ID;

这可能看起来像SELECT DISTINCT答案的一个微不足道的变化,但它不是出于多种原因:

  1. 在大型数据集上,网上提供了大量示例,其中GROUP BY的执行速度明显快于SELECT DISTINCT。虽然我们作为程序员可能会看到两者为这种情况产生相同的结果集,但是这两种操作的语义是不同的,并且在某些情况下输出实际上是不同的 - 例如每当有计算列时。

    • SELECT DISTINCT定义为执行SORT,然后消除重复项。因此,存储要求需要足够的额外空间来存储工作结果集,以及所选 sort 算法所需的任何内容。
    • GROUP BY被定义为收集存储桶,因此存储要求仅适用于实际存在的存储桶数量(即唯一值)。

    两者的时间要求是n * Log(n)。当 tempdb 不在SSD上时,性能差异可能更明显。

  2. 所有 REAL SQL程序员都知道DISTINCT的任何使用看起来都是业余的(可能由有意识或无意识的,以及对上述性能差异的理解)。因此,那些不想成为业余爱好者的SQL程序员总是将SELECT DISTINCT替换为GROUP BY作为原则。我的舌头在这里坚定不移 - 但鉴于上述第(1)点,这实际上是 记住 的有效理由,几乎所有SELECT DISTINCT的有效用途都可以替换为GROUP BY。

  3. 使用SELECT DISTINCT的最常见情况是缺少JOIN子句导致人为重复。业余SQL程序员不理解这一事实,然后他们使用SELECT DISTINCT消除重复项。调整业余爱好者编写的SQL的最常用方法之一是简单地搜索SELECT DISTINCT的所有用法并添加缺少的JOIN子句,或者如果实际需要消除重复项,则利用(1)并替换为GROUP BY 。非业余SQL程序员发出信号表示此步骤是由于没有使用SELECT DISTINCT而执行的,从而为任何审阅者节省了这样做的努力。