Sum of specific values in SQL

我是研究僧i 提交于 2019-12-12 04:22:25

问题


I'm trying to find the sum of specific values within a table, using SQL. A sample table is:

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

I have 35 such 'Code' columns and values.

What I need is selecting a table having only one code. Say I need Code AA3, this would be (the Code column is not required here, but only to show where I got the values):

+-------+-------+--------+
|  ID   | Code  |  Value |
+-------+-------+--------+
|  01   |  AA3  |  328.34|
|  02   |  AA3  |  234.56|
|  03   |  AA3  |       0|
+-------+-------+--------+

And I will later need another (separate) query which contains the sum of several codes, for example the sum of codes AA1 and AA2 together.

+-------+---------+
|  ID   |   Value |
+-------+---------+
|  01   |     34.2|
|  02   |     27.0|
|  03   |   409.01|
+-------+---------+

I was thinking about having a 'WHERE' and run on every 35 columns, but that would really be tedious and this does not seem too efficient. I was wondering if there was a way to do that through SQL (I can do it with Excel with an if statement and it works wonders).

Maybe if there was a way to 'search' through a row, return the column name and then use that column name to retrieve the number?

Let me know if you require more information =)


回答1:


What you should do is store your data in a normalised form.

However...

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

will return the results you seek




回答2:


Your table structure is less than ideal. I'll show you a straight forward example similar to your Excel based IF method, and then a much simpler query with a normalised data-structure.

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

With 30 codes per id, you need 30 CASE statements.

The alternative is to have several rows of data per id, instead of several columns per 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|
+-------+-------+-------+-------+ 

The the query is simple, you can add as many observations as you like without changing the table structure, and a whole host of other advantages...

 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


来源:https://stackoverflow.com/questions/11825158/sum-of-specific-values-in-sql

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!