SQL中特定值的总和
我正在尝试使用SQL查找表中特定值的总和。示例表为:SQL中特定值的总和,sql,sql-server-2008-r2,sum,rows,multiple-columns,Sql,Sql Server 2008 R2,Sum,Rows,Multiple Columns,我正在尝试使用SQL查找表中特定值的总和。示例表为: +-------+-------+-------+-------+-------+-------+-------+ | ID | Co1 | Va1 | Co2 | Va2 | Co3 | Va3 | +-------+-------+-------+-------+-------+-------+-------+ | 01 | AA1 | 23.0| AA2 | 11.2| AA3 |
+-------+-------+-------+-------+-------+-------+-------+
| ID | Co1 | Va1 | Co2 | Va2 | Co3 | Va3 |
+-------+-------+-------+-------+-------+-------+-------+
| 01 | AA1 | 23.0| AA2 | 11.2| AA3 | 328.34|
| 02 | AA2 | 27.0| AA3 | 234.56| AA4 | 23.8|
| 03 | AA1 | 409.01| AA4 | 234.98| NULL | NULL |
+-------+-------+-------+-------+-------+-------+-------+
我有35个这样的“代码”列和值
我需要的是选择一个只有一个代码的表。假设我需要代码AA3,这将是(这里不需要代码列,只是为了显示我从哪里获得的值):
稍后我将需要另一个(单独的)查询,它包含几个代码的总和,例如代码AA1和AA2的总和
+-------+---------+
| ID | Value |
+-------+---------+
| 01 | 34.2|
| 02 | 27.0|
| 03 | 409.01|
+-------+---------+
我曾考虑过在每35个栏目中设置一个“WHERE”并运行一次,但这真的很乏味,而且似乎效率不高。我想知道是否有一种方法可以通过SQL实现这一点(我可以用Excel和if语句来实现,效果非常好)
如果有一种方法可以“搜索”一行,返回列名,然后使用该列名检索数字
如果您需要更多信息,请告诉我=)您应该做的是以标准化形式存储数据 然而
select SUM(v)
from
(
select * -- ID, r, v
from
(select * from yourtable) u
unpivot
( r for co in (co1, co2, co3)) as u1
unpivot
( v for va in (va1, va2, va3)) as u2
where RIGHT(co,1) = RIGHT(va,1)
) v
WHERE R = 'AA1' -- etc
将返回您搜索的结果您的表结构不太理想。我将向您展示一个类似于基于Excel的
IF
方法的简单示例,然后是一个具有规范化数据结构的更简单的查询
SELECT
id,
CASE WHEN co1 = 'AA1' THEN co1 ELSE 0 END
+ CASE WHEN co2 = 'AA1' THEN co2 ELSE 0 END
+ CASE WHEN co3 = 'AA1' THEN co3 ELSE 0 END
+ CASE WHEN co4 = 'AA1' THEN co4 ELSE 0 END
+ etc, etc
FROM
yourTable
每个id
有30个代码,您需要30个CASE
语句
另一种方法是每个id
有几行数据,而不是每个id
有几列数据
+-------+-------+-------+-------+
| ID | Obs | Cod | Val |
+-------+-------+-------+-------+
| 01 | 1 | AA1 | 23.0 |
| 01 | 2 | AA2 | 11.2 |
| 01 | 3 | AA3 | 328.34|
| 02 | 1 | AA2 | 27.0|
| 02 | 2 | AA3 | 234.56|
| 02 | 3 | AA4 | 23.8|
| 03 | 1 | AA1 | 409.01|
| 03 | 2 | AA4 | 234.98|
+-------+-------+-------+-------+
查询很简单,您可以添加任意多的观察值,而无需更改表结构,还有许多其他优点
Query if one id can have several Query if one id can only have one
observations for the same code: observation for any one code:
---------------------------------- -----------------------------------
SELECT SELECT
id, *
cod, FROM
SUM(val) AS val yourTable
FROM WHERE
yourTable cod = 'AA1'
WHERE
cod = 'AA1'
GROUP BY
id,
cod
您正在使用哪些RDMB,SQL Server、Oracle和MySQL?在第一句你说“使用SQL”,你是指MS SQL Server?关于最后一个问题,您是否只有3个代码列?总数将仅适用于AA1和AA2或更多组合?啊,是的,我的错。我正在使用的是SQL Server 2008R2。出于某种原因,我没有看到您的其他评论。。。哦,好吧。是的,实际上有35个代码列和35个金额列。代码从AA1到AA652不等。对于第二部分(添加几个代码),我需要添加9个代码:AA74、AA76、AA78等等。我希望它是规范化的!>那样会简单得多。嗯,你能给我解释一下吗?我对SQL(^^;)相当陌生,例如,“For”做循环?我不知道你为什么在WHERE语句的“value”中从右取左字符……UNPIVOT取一个像你这样的非规范化表,并将其正常化(即:使其更垂直,而不是水平)。但是,它只能执行一种数据类型,因此需要执行两次才能将两种类型都输出。右侧将文本数据的最后一个字符(CO1,CO2)与值数据的最后一个字符(VA1,VA2)相匹配。尝试将总和(V)替换为*以查看整个数据集!我以为你是在取列value中的值,然后取最后一个字符!通过选择所有内容,我现在了解到,您要匹配的实际上是列名。谢谢行得通!:D(除了我在SQL server中导入的列数据类型不匹配…哦,好吧,我必须正确地重新导入它们)@Unknown008:如果您自己导入了数据,您不能在该步骤中对其进行规范化吗?可能会给你省去很多麻烦。啊,我直到现在才注意到你的评论,很抱歉回复太晚了。没有,我得到了这样的数据。我希望我以后不会得到更多这样的数据。是的,这就是为什么我不太喜欢35个WHERE语句,哈哈x3,但是不,我不能这样排序,特别是有几千条记录=(谢谢你的回答=)@Unknown008-但是要知道,该SQL不适用于您的表结构类型。您或者需要预处理数据(请参阅问题的答案)[每次执行时可能会产生大量的处理开销]、将数据标准化为适合RDBMS/SQL的数据[对重构数据进行重大投资]、或者使用高度冗余的代码[可能会产生大量的编码和维护开销]。很抱歉,您似乎有一个遗留问题(数据结构),它迫使您陷入没有“理想”方法的困境。@Unknown008-另外,请注意,有许多方法可以快速规范化数据。几千条记录实际上并不多。我明白了,谢谢你的评论(Dems=)我们实际上是在要求下次对数据进行更多的排序;每个代码都有一列,这将使使用一个简单的
从表GROUP BY id中选择SUM(列)
变得更容易。我想这一次我们将坚持使用excel。
Query if one id can have several Query if one id can only have one
observations for the same code: observation for any one code:
---------------------------------- -----------------------------------
SELECT SELECT
id, *
cod, FROM
SUM(val) AS val yourTable
FROM WHERE
yourTable cod = 'AA1'
WHERE
cod = 'AA1'
GROUP BY
id,
cod