【问题标题】:ArangoDB AQL: Find Gaps In Sequential DataArangoDB AQL:查找顺序数据中的差距
【发布时间】:2020-11-20 15:04:07
【问题描述】:

我已获得数据来构建具有产品部件号形式的顺序数据的应用程序:"000000", "000001", "000002", "000010", "000011" ...。以前的应用程序是一个旧的 MS Access 数据库,在零件编号生成器中没有任何间隙填充功能,因此 "000002""000010" 之间的间隙(是的,它们也是字符串,但我可以使用它。 ..)。

我们可以继续根据最后一个值递增并忽略空白,但是,为了尝试将所有可用的数字用于我们的命名方案,我们希望能够填补空白。我们的命名方案使用前两位数字来描述“产品系列”,这样:[00]0000 将是与 [02]0000 不同的系列。

我可以使用以下方法找到起始值和结束值:

let query = `
  LET first = (
    MIN(
      FOR part in part_search
        SEARCH STARTS_WITH(part.PartNumber, @family)
        RETURN part.PartNumber
    )
  )
  LET last = (
    MAX(
      FOR part in part_search
        SEARCH STARTS_WITH(part.PartNumber, @family)
        RETURN part.PartNumber
    )
  )
  RETURN { first, last }
`

上面的例子返回:{first: "000000", last: "000915"}

使用 ArangoDB 和 AQL,我如何才能找到这些差距?我找到了一些 SQL 示例,但我觉得 AQL 的功能有点限制。

提前致谢!

【问题讨论】:

    标签: arangodb aql


    【解决方案1】:

    首先,我认为获得最小值/最大值的最佳选择是使用聚合:

    FOR part in part_search
        SEARCH STARTS_WITH(part.PartNumber, @family)
        COLLECT x = 1
        AGGREGATE first = MIN(part.PartNumber), last = MAX(part.PartNumber)
        RETURN {
            first: first,
            last: last
        }
    

    但这在尝试寻找差距时并没有真正的帮助。你是对的 - SQL 有几个可以提供帮助的逻辑结构(比如使用变量和游标迭代),但即便如此,我也不鼓励这种模式。

    更好的方法可能是使用“蛮力”方法 - 将包含现有数字的表格与 所有 数字的表格进行比较,使用像 JOIN 这样的原生方法来找出差异.以下是您在 AQL 中的执行方式:

    LET allNumbers = 0..9999
    LET existingParts = (
        FOR part in part_search
            SEARCH STARTS_WITH(part.PartNumber, @family)
            LET childId = RIGHT(part.PartNumber, 4)
            RETURN TO_NUMBER(childId)
    )
    RETURN MINUS(allNumbers, existingParts)
    

    x..y 构造创建了一个序列(一个数字数组),我们将其用作完整的可能数字集。然后,我们只想返回 ID 的“非家庭”部分(我称之为“孩子”),它需要是数字才能与之前的集合进行比较。然后,我们使用MINUSallNumbers 列表中删除existingParts 的元素。

    需要注意的一点是,该查询将仅返回部件号的“子”部分,因此您必须稍后将其加入到系列号中。或者,您也可以跳过字符串拆分,并在创建列表时获得“花式”:

    LET allNumbers = TO_NUMBER(CONCAT(@family, '0000'))..TO_NUMBER(CONCAT(@family, '9999'))
    LET existingParts = (
        FOR part in part_search
            SEARCH STARTS_WITH(part.PartNumber, @family)
            RETURN TO_NUMBER(part.PartNumber)
    )
    RETURN MINUS(allNumbers, existingParts)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多