使用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查找级别值或最佳值吗?
答案 0 :(得分:2)
您不应该以字符串格式存储start_level
和end_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
;