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 |

我正在尝试使用SQL查找表中特定值的总和。示例表为:

+-------+-------+-------+-------+-------+-------+-------+
|  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