将两个非数字列相加

时间:2017-06-22 02:12:20

标签: sql oracle aggregate-functions

使用oracle 12c。我有4列:

country   student_id (primary)  start_level     end_level
-------   --------------------  -----------     ---------
India     I20                   L3              L12
India     I21                   L5              L9
China     c10                   L4              L11
USA       U20                   L2              L9
Canada    C20                   L9              L12

从上面的表格结构中,我希望按国家/地区划分总体学生的水平总和。例如,输出如下:

Country|  Total_students| Total_levels
India                  2            15

(总水平计算:L3到L12 = 10 + L5到L9 = 5.所以,总水平15)

我可以使用substr查找级别值或最佳值吗?

3 个答案:

答案 0 :(得分:2)

您不应该以字符串格式存储start_levelend_level,它应该是一个整数,您应该将L放在它前面(即{ {1}}只是整数L3。)我假设你现在不能重新设计数据库,所以请尝试以下方法:

3

这使用公用表表达式(WITH子句)将表转换为具有整数格式数的表。 WITH temp_table AS ( SELECT country, student_id, CAST(SUBSTR(start_level,2,10) AS INT) AS start_int, CAST(SUBSTR(end_level,2,10) AS INT) AS end_int FROM my_table) SELECT COUNTRY, COUNT(student_id) AS TOTAL_STUDENTS, SUM(end_int - start_int + 1) AS Total_Levels FROM temp_table GROUP BY COUNTRY ORDER BY COUNTRY 命令将从第二个数字开始,然后转到下一个数字。在这种情况下,它没有那么多,所以它会在字符用完时停止。例如,如果您有级别SUBSTR(),那么您将不得不增加该参数(我不希望这种情况发生)。之后,它使用L12000000000将该字符串转换为整数格式。

现在您已准备好从CTE中进行选择。如图所示,查询相当直接。

答案 1 :(得分:1)

您可以使用regexp_substr()提取数字:

select country,
       sum(cast(regexp_substr(end_level, '[0-9]+') as number) -
           cast(regexp_substr(start_level, '[0-9]+') as number) +
           1)

from t
group by country;

答案 2 :(得分:1)

这样的东西
select   country, count(student_id) as total_students,
         sum(to_number(substr(end_level, 2)) - to_number(substr(start_level, 2)) + 1 )
                                    as total_levels
from     your_table
group by country
;