我有一个非常棘手的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
开头的设备有三个连接到电源板的连接。
如果我使用DISTINCT
和GROUP 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 BY
,DISTINCT
和SUM(DISTINCT)
进行了游戏,似乎无法获得我需要的输出。
真的很感激任何帮助。
非常感谢
西蒙
答案 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答案的一个微不足道的变化,但它不是出于多种原因:
在大型数据集上,网上提供了大量示例,其中GROUP BY的执行速度明显快于SELECT DISTINCT。虽然我们作为程序员可能会看到两者为这种情况产生相同的结果集,但是这两种操作的语义是不同的,并且在某些情况下输出实际上是不同的 - 例如每当有计算列时。
两者的时间要求是n * Log(n)。当 tempdb 不在SSD上时,性能差异可能更明显。
所有 REAL SQL程序员都知道DISTINCT的任何使用看起来都是业余的(可能由有意识或无意识的,以及对上述性能差异的理解)。因此,那些不想成为业余爱好者的SQL程序员总是将SELECT DISTINCT替换为GROUP BY作为原则。我的舌头在这里坚定不移 - 但鉴于上述第(1)点,这实际上是 记住 的有效理由,几乎所有SELECT DISTINCT的有效用途都可以替换为GROUP BY。
使用SELECT DISTINCT的最常见情况是缺少JOIN子句导致人为重复。业余SQL程序员不理解这一事实,然后他们使用SELECT DISTINCT消除重复项。调整业余爱好者编写的SQL的最常用方法之一是简单地搜索SELECT DISTINCT的所有用法并添加缺少的JOIN子句,或者如果实际需要消除重复项,则利用(1)并替换为GROUP BY 。非业余SQL程序员发出信号表示此步骤是由于没有使用SELECT DISTINCT而执行的,从而为任何审阅者节省了这样做的努力。