我正在尝试匹配一段代码的排序顺序。以下两个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;添加了索引。
答案 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.