【问题标题】:Specifying starting value in sorting/Sort starting from middle - Progress openedge在排序中指定起始值/从中间开始排序 - Progress opensge
【发布时间】:2017-03-17 15:45:35
【问题描述】:

场景:我的表中有一个字符字段(名称:优先级),其中值存储为 1、2、3 和空白(“”)。

for each mytable no-lock by priority:

此查询按以下顺序排序:空白、1、2、3。

for each mytable no-lock by priority desc:

并且,此查询对记录进行排序:3、2、1 和空白。

但我需要像这样对记录进行排序:1、2、3,然后是空白。按升序但跳过空白并从 1 开始。 有什么办法可以在进行中解决这个问题吗?

【问题讨论】:

    标签: sorting progress-4gl openedge


    【解决方案1】:

    由于您使用的是字符字段,因此它将数字视为字符串。字符串“1”、“2”和“3”的 ASCII 值是 49、50 和 51。Progress 将空白 (“”) 视为 ASCII -1。这就是为什么首先出现空白的原因。

    最好的办法是使用两个FOR EACH 语句。先做非空记录:

    FOR EACH mytable NO-LOCK WHERE mytable.priority <> "" BY priority:
    

    然后做空白记录:

    FOR EACH mytable NO-LOCK WHERE mytable.priority = "":
    

    如果您在过程/函数中有业务逻辑,则可以在 FOR EACH 循环中运行它们以防止任何代码重复。

    【讨论】:

    • 这几乎可以做到。确保将优先级编入索引以获得最佳性能。
    • @bupereira 实际上我认为索引并不重要。至少对于第一个 FOR EACH 不会: 将触发表扫描/全索引搜索。
    • @TheDrooper 这是个好建议。实际上,就我而言,使用的查询并不是那么简单,我确实需要一次所有结果
    • @Mahesh 在这种情况下,您可以尝试添加一个排序字段,如其他答案中所述。如果您无法更改架构,请将记录复制到临时表并像您一样分配排序字段。然后你可以在临时表上使用一个 FOR EACH。
    【解决方案2】:

    如果(仅当)表中的记录不多,也许您可​​以将记录复制到具有新优先级的临时表中,然后对临时表进行排序?

    如果您有数百万条记录,这可能不是它!然后我会考虑简单地添加一个新字段。

    DEFINE TEMP-TABLE MyTable NO-UNDO
        FIELD priority AS CHARACTER
        FIELD txt      AS CHARACTER.
    
    CREATE MyTable.
    ASSIGN MyTable.priority = "1"
           MyTable.txt      = "First?".
    
    CREATE MyTable.
    ASSIGN MyTable.priority = ""
           MyTable.txt      = "Last?".
    
    DEFINE TEMP-TABLE ttMyTable NO-UNDO LIKE MyTable
        FIELD newPriority AS INTEGER
        INDEX sortOrder newPriority.
    
    FOR EACH MyTable NO-LOCK:
        CREATE ttMyTable.
        BUFFER-COPY MyTable TO ttMyTable 
            ASSIGN 
                ttMyTable.newPriority = IF MyTable.priority = "" THEN 99999 ELSE INTEGER(MyTable.priority).
    END.
    
    FOR EACH ttMyTable NO-LOCK BY ttMyTable.newPriority:
        DISPLAY ttMyTable.
    END.
    

    【讨论】:

    • 其实我用的是动态查询,因为查询需要根据提供的搜索参数来准备,我觉得不可能吧?
    【解决方案3】:

    由于您正在扫描 /all/ 记录,您可以按 BY 排序:

    define temp-table tt no-undo
       field priority as character
       .
    
    create tt. tt.priority = "".
    create tt. tt.priority = "1".   
    create tt. tt.priority = "2".   
    create tt. tt.priority = "3".   
    create tt. tt.priority = "".
    
    for each tt by ( if tt.priority = "" then "4" else tt.priority ):
    
       display string( rowid( tt ) ) tt.priority.
    
    end.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-10
      • 1970-01-01
      • 2011-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多