当前位置: 首页 > 面试题库 >

BigQuery如何处理语义版本数据类型

冯育
2023-03-14
问题内容

我知道BigQuery中没有数据类型。您希望在BigQuery中处理什么语义版本?

我有以下架构:

software:string,
software_version:string

software_version列是string但我存储在其中的数据为semver格式:`MAJOR.MINOR.PATCH-prerelease

我特别想执行运算符< > =

select '4.0.0' < '4.0.0-beta'

返回true,但是根据semver的定义,它是错误的。因为char-用于预发布。


问题答案:

以下是BigQuery标准SQL

您可以使用compareSemanticVersionUDF比较两个语义版本
和/或使用normaizedSemanticVersionUDF通过ORDER BY子句对输出进行排序。
参见下面的示例(将比较用例和排序依据)合二为一

#standardSQL
CREATE TEMP FUNCTION normaizedSemanticVersion(semanticVersion STRING) 
AS ((
  SELECT STRING_AGG(
      IF(isDigit, REPEAT('0', 8 - LENGTH(chars)) || chars, chars), '' ORDER BY grp 
    ) || 'zzzzzzzzzzzzzz' 
  FROM (
    SELECT grp, isDigit, STRING_AGG(char, '' ORDER BY OFFSET) chars,
    FROM (
      SELECT OFFSET, char, isDigit,
        COUNTIF(NOT isDigit) OVER(ORDER BY OFFSET) AS grp
      FROM UNNEST(SPLIT(semanticVersion, '')) AS char WITH OFFSET, 
      UNNEST([char IN ('1','2','3','4','5','6','7','8','9','0')]) isDigit
    )
    GROUP BY grp, isDigit
)));
CREATE TEMP FUNCTION compareSemanticVersions(
  normSemanticVersion1 STRING, 
  normSemanticVersion2 STRING) 
AS ((
  SELECT CASE 
      WHEN v1 < v2 THEN 'v2 newer than v1'
      WHEN v1 > v2 THEN 'v1 newer than v2'
      ELSE 'same versions'
    END
  FROM UNNEST([STRUCT(
    normaizedSemanticVersion(normSemanticVersion1) AS v1, 
    normaizedSemanticVersion(normSemanticVersion2) AS v2
  )])
));
WITH test AS (
  SELECT '1.10.0-alpha' AS v1 , '1.0.0-alpha.1' AS v2 UNION ALL
  SELECT '4.0.0', '4.0.0-beta' UNION ALL
  SELECT '1.0.0-alpha.1'     , '1.0.0-alpha.beta' UNION ALL
  SELECT '1.0.0-alpha.beta'  , '1.0.0-beta' UNION ALL
  SELECT '1.0.0-beta'        , '1.0.0-beta.2' UNION ALL
  SELECT '1.0.0-beta.2'      , '1.0.0-beta.11' UNION ALL
  SELECT '1.0.0-beta.11'     , '1.0.0-rc.1' UNION ALL
  SELECT '1.0.0-rc.1'        , '1.0.0' UNION ALL
  SELECT '1.0.0-alpha-1.1+build1234-a', '1.0.0-alpha-1.1+build1234-a'
)
SELECT v1, v2, compareSemanticVersions(v1, v2) result
FROM test 
ORDER BY normaizedSemanticVersion(v1)

带输出

Row v1                              v2                              result   
1   1.0.0-alpha-1.1+build1234-a     1.0.0-alpha-1.1+build1234-a     same versions    
2   1.0.0-alpha.1                   1.0.0-alpha.beta                v2 newer than v1     
3   1.0.0-alpha.beta                1.0.0-beta                      v2 newer than v1     
4   1.0.0-beta.2                    1.0.0-beta.11                   v2 newer than v1     
5   1.0.0-beta.11                   1.0.0-rc.1                      v2 newer than v1     
6   1.0.0-beta                      1.0.0-beta.2                    v1 newer than v2     
7   1.0.0-rc.1                      1.0.0                           v2 newer than v1     
8   1.10.0-alpha                    1.0.0-alpha.1                   v1 newer than v2     
9   4.0.0                           4.0.0-beta                      v1 newer than v2

注意:我在阅读您提供的参考资料后,根据对语义版本控制的理解,在上面编写了UDF。潜在的一些极端情况仍然需要解决。但是绝对应该适用于简单的情况,我希望您将能够简单地采用这些UDF并根据您的特定需求调整输出,甚至可以优化我最终在这里使用的IDF。

仅供参考:在normaizedSemanticVersionUDF中,我zzzzzzzzzz仅用于解决一些极端情况。我尝试的另一个选择是..zzzzzzzzzz(请注意两个额外的点)-我认为这对于更复杂的情况会提供更好的结果-
但是我真的没有时间完成测试。请试试

例如,在“语义版本控制”页面中,有一个示例:1.0.0-alpha <1.0.0-alpha.1 <1.0.0-alpha beta <1.0.0-beta
<1.0.0-beta.2 <1.0。 0-beta.11 <1.0.0-rc.1 <1.0.0。

要使用与该示例相同的顺序-..zzzzzzzzzz应该使用-参见下文

#standardSQL
CREATE TEMP FUNCTION normaizedSemanticVersion(semanticVersion STRING) 
AS ((
  SELECT STRING_AGG(
      IF(isDigit, REPEAT('0', 8 - LENGTH(chars)) || chars, chars), '' ORDER BY grp 
    ) || '..zzzzzzzzzzzzzz' 
  FROM (
    SELECT grp, isDigit, STRING_AGG(char, '' ORDER BY OFFSET) chars,
    FROM (
      SELECT OFFSET, char, isDigit,
        COUNTIF(NOT isDigit) OVER(ORDER BY OFFSET) AS grp
      FROM UNNEST(SPLIT(semanticVersion, '')) AS char WITH OFFSET, 
      UNNEST([char IN ('1','2','3','4','5','6','7','8','9','0')]) isDigit
    )
    GROUP BY grp, isDigit
)));
CREATE TEMP FUNCTION compareSemanticVersions(
  normSemanticVersion1 STRING, 
  normSemanticVersion2 STRING) 
AS ((
  SELECT
    CASE 
      WHEN v1 < v2 THEN 'v2 newer than v1'
      WHEN v1 > v2 THEN 'v1 newer than v2'
      ELSE 'same versions'
    END
  FROM UNNEST([STRUCT(
    normaizedSemanticVersion(normSemanticVersion1) AS v1, 
    normaizedSemanticVersion(normSemanticVersion2) AS v2
  )])
));
WITH test AS (
  SELECT 1 `order`, '1.0.0-alpha' version UNION ALL
  SELECT 2, '1.0.0-alpha.1' UNION ALL
  SELECT 3, '1.0.0-alpha.beta' UNION ALL
  SELECT 4, '1.0.0-beta' UNION ALL
  SELECT 5, '1.0.0-beta.2' UNION ALL
  SELECT 6, '1.0.0-beta.11' UNION ALL
  SELECT 7, '1.0.0-rc.1' UNION ALL
  SELECT 8, '1.0.0.' 
)
SELECT *
FROM test
ORDER BY normaizedSemanticVersion(version)

输出与语义版本控制规范匹配

Row order   version  
1   1   1.0.0-alpha  
2   2   1.0.0-alpha.1    
3   3   1.0.0-alpha.beta     
4   4   1.0.0-beta   
5   5   1.0.0-beta.2     
6   6   1.0.0-beta.11    
7   7   1.0.0-rc.1   
8   8   1.0.0.


 类似资料:
  • 我在我的工作场所开始学习詹金斯。我们对Teamcity使用语义版本控制,我想在Jenkins上实现同样的功能。当我将工件存储在builds文件夹($JENKINS_HOME/jobs/$JOB_NAME/builds/$BUILD_NUMBER)中时,出现了我的问题,因为JENKINS仅使用BUILD_NUMBER为BUILD创建文件夹,因此当我必须重置反BUILD_NUMBER时,未来工件将存储

  • (自己模拟的数据效果) 如上路径动画,目前的问题是运行的坐标数据是依照地图来的 需要转换为画布能够展示的范围,但运行数据之前差别大部分情况下都很小 我要怎样处理会合适一点? help大佬们

  • 校验者: @NellyLuo @那伊抹微笑 @微光同尘 翻译者: @Lielei 本指南旨在一个单独实际任务中探索一些主要的 scikit-learn 工具: 分析关于 20 个不同主题的一个文件集合(新闻组帖子)。 在本节中,我们将会学习如何: 读取文件内容以及所属的类别 提取合适于机器学习的特征向量 训练一个线性模型来进行分类 使用网格搜索策略找到特征提取组件和分类器的最佳配置 教程设置 开始

  • 我们有一个DynamoDb表,其中一个列名“createdAt”有时创建为S(String)数据类型,有时创建为N(Number)数据类型。 在我的代码中,如果我定义为String,当我想获取数据时它会失败,它是数字: 如果我定义为Number,当我想获取数据并且它是表中的字符串时失败: 你们有没有人以前也有过同样的问题?应该有办法解决它对吗?并且不能只选择一种数据类型:(

  • 问题内容: 我正在尝试从下面给出的Java版本输出中获取‘6’ 同样,我写了这个批处理脚本 显示“ 1.6.0_21” 有人可以指导我正确的方向吗?我不太熟悉。 问题答案: 在第一个循环中,说我们将仅使用命令输出中的第三个标记。无需将命令的输出重定向到文件,我们可以在循环本身中运行此命令。插入记号()是转义字符,并且需要,所以我们可以嵌入,并在命令字符串符号。 在循环体内,我们设置了一个新的var

  • 本文向大家介绍C#自定义处理xml数据类实例,包括了C#自定义处理xml数据类实例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了C#自定义处理xml数据类。分享给大家供大家参考。具体分析如下: 这个C#类专门用户处理xml数据,可以大大简化xml的操作,类中封装了常用的xml操作,包括打开、读取xml数据,读取、写入节点数据,通过xpath读取节点数据,导出节点数据等等,还可以根据需要自