两个不同的FOR EACH(BREAK BY with JOIN)循环给出意想不到的不同结果?

时间:2016-09-27 15:45:44

标签: sorting progress-4gl openedge

我正在尝试匹配一段代码的排序顺序。以下两个FOR EACH语句中的字段和比较是相同的,除了Item.PID在一个查询中请求特定值,而Item.Bill在另一个查询中要求特定值。但是,这两个查询以不同的顺序返回记录。

Item表的主要索引是Comp,PID,ItemID,IndNum。 Patient表的主要唯一索引是PatID - Comp,ID。

FOR EACH Item
    WHERE Item.Comp   = 1 
      AND Item.Bill   > 0 
      AND Item.PID    = 123
      AND Item.Store  <> ? 
      AND Item.SecNum  > 0   
      AND Item.TerNum <> ? 
      AND Item.Desc   <> ? 
      AND Item.Date   <> ? 
      AND Item.Code   <> ""
      AND Item.Type    = "P" 
      AND Item.BillDate = 09/14/2016
      AND Item.Method   = "P" 
    NO-LOCK,
    FIRST Patient USE-INDEX PatID
    WHERE Patient.Comp = Item.Comp
      AND Patient.ID = Item.PID
    NO-LOCK
    BREAK BY Item.Comp
          BY Item.Bill
          BY Patient.LName
          BY Patient.FName
          BY Item.PID
          BY Item.Store
          BY Item.SecNum
          BY Item.TerNum
          BY Item.Desc
          BY Item.Date
          BY Item.Code:
  DISPLAY Amt.
END.

FOR EACH Item
    WHERE Item.Comp   = 1 
      AND Item.Bill   = 456
      AND Item.PID    > 0
      AND Item.Store  <> ? 
      AND Item.SecNum  > 0   
      AND Item.TerNum <> ? 
      AND Item.Desc   <> ? 
      AND Item.Date   <> ? 
      AND Item.Code   <> ""
      AND Item.Type    = "P" 
      AND Item.BillDate = 09/14/2016
      AND Item.Method   = "P" 
    NO-LOCK,
    FIRST Patient USE-INDEX PatID
    WHERE Patient.Comp = Item.Comp
      AND Patient.ID = Item.PID
    NO-LOCK
    BREAK BY Item.Comp
          BY Item.Bill
          BY Patient.LName
          BY Patient.FName
          BY Item.PID
          BY Item.Store
          BY Item.SecNum
          BY Item.TerNum
          BY Item.Desc
          BY Item.Date
          BY Item.Code:
  DISPLAY Amt.
END.

第一个查询返回四个记录,其中Item.Amt字段中的值的顺序为:

827, 1124, 300, 102.

第二个返回四个记录,其中Item.Amt字段中的值的顺序为:

827, 1124, 102, 300.

从第二个查询中删除Patient.LName的Break By匹配第一个查询的排序,但显然不能正确排序我的结果(对于多个患者)。我只是觉得这可能是问题所在。

修改 - 指定字段&#39; Amt&#39;属于表&#39;项目&#39;。为表&#39;患者&#39;添加了索引。

2 个答案:

答案 0 :(得分:2)

如果不共享表的索引定义,就不可能真正说明发生了什么。

但如果我不得不猜测我会认为使用&#34; FIRST患者&#34;是你问题的根源。永远不会做你(可能)认为它做的事情。它返回满足WHERE子句中条件的第一条记录(使用选定或指定的索引),而不考虑BY短语。 IOW - patient.lname不会发挥作用来确定哪个患者是&#34; FIRST&#34;。

你可能会有更好的运气转换到&#34;每个病人&#34;并取消USE-INDEX。 (你可能还需要在块中使用诸如FIRST-OF等函数来添加一些逻辑 - 我不能说基于你对索引的了解很少。)

&#34;每个项目&#34;查询的某些部分可能会使用不同的索引,因为您有不同的字段集,并且匹配相等。这种匹配驱动索引选择算法的第一部分。结合FOR FIRST的行为,你有足够的scop来处理不同的排序顺序。

答案 1 :(得分:0)

Progress根据WHERE和BREAK语句确定要使用的最佳索引。更改这些可能会更改使用的索引,这可能会更改记录的顺序。如果使用动态查询,则可以使用INDEX-INFORMATION属性查看Progress选择的索引。

DEFINE VARIABLE hQuery AS HANDLE NO-UNDO.
DEFINE VARIABLE cForEach AS CHARACTER NO-UNDO.
DEFINE BUFFER bfItem FOR Item.

cForEach = "FOR EACH bfItem".

CREATE QUERY hQuery.
hQuery:SET-BUFFERS(BUFFER bfItem:HANDLE).
hQuery:QUERY-PREPARE(cForEach).
hQuery:QUERY-OPEN().
hQuery:GET-FIRST(NO-LOCK).

MESSAGE hQuery:INDEX-INFORMATION[1] VIEW-AS ALERT-BOX.