计算 Row Wise Sum - Sql server
Posted
技术标签:
【中文标题】计算 Row Wise Sum - Sql server【英文标题】:calculate Row Wise Sum - Sql server 【发布时间】:2018-06-25 14:37:26 【问题描述】:这是我的桌子:
ID Q1 Q2 Q3 Q4
----------------------------------------------------------------
20130712 NULL 728.63 NULL NULL
20130712 8881.55 9673.68 2629.566 6251.984
20130713 1813 1813 84.49 1728.51
20130714 3632.65 3632.65 1209.412 2423.238
20130714 70.758 2637.43 70.758 0
20130714 1601.578 3569.73 204.745 1396.833
20130714 728.63 728.63 0 728.63
20130714 1401.629 2251.39 94.418 1307.211
20130715 583.956 5089.19 583.956 0
20130805 6317.277 8958 2629.566 3687.711
我想要下面的输出。(列可能会动态变化,需要逐行计算总和)
ID Q1 Q2 Q3 Q4 SUM(Q1:Q4)
---------------------------------------------------------------------------
20130712 NULL 728.63 NULL NULL 728.63
20130712 8881.55 9673.68 2629.566 6251.984 27436.78
20130713 1813 1813 84.49 1728.51 5439
20130714 3632.65 3632.65 1209.412 2423.238 ...
20130714 70.758 2637.43 70.758 0
20130714 1601.578 3569.73 204.745 1396.833
20130714 728.63 728.63 0 728.63
20130714 1401.629 2251.39 94.418 1307.211
20130715 583.956 5089.19 583.956 0
20130805 6317.277 8958 2629.566 3687.711
【问题讨论】:
输出只是没有Total
列的原始表。你把它们弄反了吗?
【参考方案1】:
在 Roman Pekar 上扩展,如果您正在使用临时表并想要这样做,您需要像这样使用 tempdb:
select
@stmt = isnull(@stmt + ', ', '') + '[' + name + ']',
@stmt1 = isnull(@stmt1 + ', ', '') + '(' + '[' + name + ']'+ ')'
from tempdb.sys.columns
where object_id = object_id('tempdb..##TempTable') and name not in ('ID')
--ID would be one of the column names you DONT want to sum.
--also notice the double pound sign. you need to declare your temp table with double pounds or it wont work
--also notice how I put brackets around name, that's because my columns weren't working because they had slashes in their names.
--the rest of the code is the same
select @stmt =
'select Date_Packed, ' + @stmt + '' +
', (select sum(S.Q) from (values ' + @stmt1 +
') as S(Q) where S.Q is not null) as [Total] ' +
'from tempdb..##TempTableas T'
print @stmt
exec sp_executesql @stmt = @stmt
--don't forget to drop it
drop table ##TempTable
【讨论】:
【参考方案2】:不知道是否有更短的方法,但我能做的最优雅的是:
select
ID, Q1, Q2, Q3, Q4,
(
select sum(S.Q)
from (values (Q1), (Q2), (Q3), (Q4)) as S(Q)
where S.Q is not null
) as [Total]
from Table1 as T
sql fiddle demo
如果您想要动态 SQL,请尝试类似
declare @stmt nvarchar(max), @stmt1 nvarchar(max)
select
@stmt = isnull(@stmt + ', ', '') + name,
@stmt1 = isnull(@stmt1 + ', ', '') + '(' + name + ')'
from sys.columns
where object_id = object_id('Table1') and name not in ('ID')
select @stmt =
'select ID, ' + @stmt +
', (select sum(S.Q) from (values ' + @stmt1 +
') as S(Q) where S.Q is not null) as [Total] ' +
'from Table1 as T'
exec sp_executesql @stmt = @stmt
sql fiddle demo
【讨论】:
需要一些助手:结果集中的列可能会增加或减少,那么如果我们硬核列名,查询可能不会给出正确的结果。所以请帮我做动态查询。【参考方案3】:您还没有显示您的查询尝试,但它可能是这样的:
SELECT
ID, Q1, Q2, Q3, Q4,
Q1 + Q2 + Q3 + Q4 AS "Total"
FROM MyTable
如果 Q1
、Q2
、Q3
或 Q4
值中的任何一个为 null,则 Q1 + Q2 + Q3 + Q4
将为 null。要将空值视为零并获得适当的总和,请改为执行以下操作:
SELECT
ID, Q1, Q2, Q3, Q4,
COALESCE(Q1,0) + COALESCE(Q2,0) + COALESCE(Q3,0) + COALESCE(Q4,0) AS "Total"
FROM MyTable
COALESCE
function 将返回列表中的第一个非空值。
【讨论】:
另一种选择是使用 NVL 函数,例如:NVL(Q1, 0) 如果 Q1 不为 NULL,则返回 Q1,如果 Q1 为 NULL,则返回 0 @DmitryBychenko - 不要认为 SQL Server 有NVL
。 COALESCE
是标准的/便携的。
需要一些帮助:结果集中的列可能会增加或减少,如果我们硬核列名,查询可能不会给出正确的结果。所以请帮我做动态查询。
@user1613094 - 有两种方法可以进行动态查询:(1) 使用前端语言来组装和运行查询,或者 (2) 编写使用 EXEC
的 SQL Server 过程或sp_executesql
。我建议发布一个专门关于动态 SQL 的新问题,当您发布新问题时,请 (a) 包括一些有效的 SQL 并且 (b) 小心获取正确的表和输出 - 我很确定您已将它们切换为这个问题,如果问题令人困惑,很难获得帮助。
完美运行@EdGibbs以上是关于计算 Row Wise Sum - Sql server的主要内容,如果未能解决你的问题,请参考以下文章
[Algorithm] Count Negative Integers in Row/Column-Wise Sorted Matrix
[Algorithm] Count Negative Integers in Row/Column-Wise Sorted Matrix
同样的sql在mysql运行没有问题,在oracle会报不是group by表达式的错