APP版本号的原则规范:
- 版本号是唯一的
- 且是一串数字
APP版本号的组成:
软件版本号有四部分组成:<主版本号.><子版本号>.<阶段版本号>.<日期版本号加希腊字母版本号>
希腊字母版本号共有5种:base、alpha、beta、RC、Release, 例如:2.1.0.181209_Release。
希腊字母版号:
- Alpha版:也叫α版(开发环境),此版本主要是以实现软件功能为主,通常只在软件开发者内部交流;
- Beta版:此版本相对于α版已经有了很大的改进,消除了严重的错误,但还是存在着一些缺陷,需要经过多次测试来进一步消除,此版本主要的修改对像是软件的UI;
- RC版:此版本已经相当成熟了,基本上不存在导致错误的BUG,与即将发行的正式版相差无几,测试人员基本通过的版本;
- Release版:此版本意味着“最终版本”、“上线版本”,在前面版本的一系列测试版之后,终归会有一个正式版本,是最终交付用户使用的一个版本。该版本有时也称为标准版。一般情况下,Release不会以单词形式出现在软件封面上,取而代之的是符号(R)。
而对于绝大多数APP来说,一般采用的基本都是GNU风格的版本号管理策略,APP完全版本号的组成包括三组数字“<主版本号.><子版本号>.<阶段版本号>”,也即X.Y.Z,其中X、Y、Z都为正整数。
需求:
app_version |
5.5.5.645 |
5.2.11.4530 |
android 5.5.5 |
android 5.4.15 |
数据中存在带有 ‘android 5.3.0’ 和 ‘5.4.17.635’大致两种数据格式,需要根据app版本号,拆分出机型,并对版本号进行比较
解决办法:
select
app_version
,case when split(app_version,' ')[0] rlike ('^[A-Za-z]+$') then split(app_version,' ')[0] else 'unknow' end as app_type
,case when nvl(split(app_version,' ')[1],'') != '' then split(app_version,' ')[1] else app_version end as app_version_number
,case when nvl(split(app_version,' ')[1],'') != '' then
CONCAT(
lpad(substring_index(substring_index(split(app_version,' ')[1], '.', 1), '.', -1), 2, 0),
lpad(substring_index(substring_index(split(app_version,' ')[1], '.', 2), '.', -1), 2, 0),
lpad(substring_index(substring_index(split(app_version,' ')[1], '.', 3), '.', -1), 2, 0),
lpad(substring_index(substring_index(split(app_version,' ')[1], '.', 4), '.', -1), 4, 0)
)
else
CONCAT(
lpad(substring_index(substring_index(app_version, '.', 1), '.', -1), 2, 0),
lpad(substring_index(substring_index(app_version, '.', 2), '.', -1), 2, 0),
lpad(substring_index(substring_index(app_version, '.', 3), '.', -1), 2, 0),
lpad(substring_index(substring_index(app_version, '.', 4), '.', -1), 4, 0)
)
end as pinjie_app_version
from temp_table_logs
where
ds = 20210221
and nvl(app_version,'') != ''
group by
app_version
,case when split(app_version,' ')[0] rlike ('^[A-Za-z]+$') then split(app_version,' ')[0] else 'unknow' end
,case when nvl(split(app_version,' ')[1],'') != '' then split(app_version,' ')[1] else app_version end
,case when nvl(split(app_version,' ')[1],'') != '' then
CONCAT(
lpad(substring_index(substring_index(split(app_version,' ')[1], '.', 1), '.', -1), 2, 0),
lpad(substring_index(substring_index(split(app_version,' ')[1], '.', 2), '.', -1), 2, 0),
lpad(substring_index(substring_index(split(app_version,' ')[1], '.', 3), '.', -1), 2, 0),
lpad(substring_index(substring_index(split(app_version,' ')[1], '.', 4), '.', -1), 4, 0)
)
else
CONCAT(
lpad(substring_index(substring_index(app_version, '.', 1), '.', -1), 2, 0),
lpad(substring_index(substring_index(app_version, '.', 2), '.', -1), 2, 0),
lpad(substring_index(substring_index(app_version, '.', 3), '.', -1), 2, 0),
lpad(substring_index(substring_index(app_version, '.', 4), '.', -1), 4, 0)
)
end
思路梳理:
- 数据中存在形如‘android 5.3.0’ 和 ‘5.4.17.635’大致两种数据格式,先按照‘ ’拆分,split 出app_type和app_version_number,对于无android或者ios标识的版本 as 为 ‘unknow’
- 此外,版本号number这里存在,有形如‘5.4.17.635’ 和 ‘5.3.0’两种格式数据,需要对数据使用 substring_index 和 lpad 函数进行0补全操作
- 最后对四部分数据进行 CONCAT函数 拼接,得到10位数版本号(此处可以根据需求补全第四部分版本号),方便进行版本比较
补充:
- string lpad(string str, int len, string pad):
- 左边添加 pad 参数输入的字符使字符串长度为 len,然后返回该字符串
- string substring_index(string A, string delim, int count):
- 返回字符串 A 中 delim 分隔符第 count 次匹配前的子字符串。
- 如果 count 是正数,所有到左边最后分隔符(从左边计算)都会返回。
- 如果 count 是负数,所有到右边最后分隔符(从右边计算)都会返回。当搜索 delim 时,substring_index 是大小写敏感的。
- 示例:substring_index(‘www.apache.org’, ‘.’, 2) = ‘www.apache’。
结果展示:
app_version | app_type | app_version_number | pinjie_app_version |
android 5.3.0 | android | 5.3.0 | 0503000000 |
5.4.17.635 | unknow | 5.4.17.635 | 0504170635 |
5.2.7.610 | unknow | 5.2.7.610 | 0502070610 |
5.5.0.635 | unknow | 5.5.0.635 | 0505000635 |
android 5.5.10 | android | 5.5.10 | 0505100010 |
5.5.0.194 | unknow | 5.5.0.194 | 0505000194 |