2016-09-27 6 views
0

Я пытаюсь соответствовать порядку сортировки фрагмента кода. Поля и сравнения в следующих двух операциях FOR EACH одинаковы, за исключением того, что Item.PID запрашивает определенное значение в одном запросе, а Item.Bill запрашивает определенное значение в другом. Однако два запроса возвращают записи в другом порядке.Два разных цикла FOR EACH (BREAK BY with JOIN) дают неожиданные результаты?

Основной индекс для таблицы товаров - Comp, PID, ItemID, IndNum. Основным уникальным индексом для таблицы пациентов является идентификатор 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 из второго запроса разберет спички рода первого запроса, но, очевидно, не будет правильно сортировать мои результаты (для нескольких пациентов). Я просто подумал, что это может быть проблема.

Редактировать - указано поле 'Amt' принадлежит к таблице 'Item'. Добавлен индекс для таблицы «Пациент».

+0

Вы уверены, что используете один и тот же набор результатов для обоих запросов? Я не знаю, как бы я это знал - я вижу одно значение поля, которое может быть из множества разных исходных записей для всего, что я знаю. В частности, мне было бы интересно узнать, что вы получаете, когда добавляете patient.LName в инструкцию DISPLAY. На самом деле было бы интересно увидеть ВСЕ возвращаемые поля DISPLAYed. –

ответ

2

Не разделяя определения индексов для таблиц, невозможно сказать, что происходит.

Но если бы я должен был догадаться, я бы подумал, что, вероятно, использование «ПЕРВЫЙ пациент» - это корень вашей проблемы. FOR FIRST не делает то, что вы (возможно) думаете, что это так. Он возвращает первую запись, которая удовлетворяет критериям в предложении WHERE (с использованием выбранного или указанного индекса) без каких-либо соображений по фразам BY. IOW - patient.lname не входит в игру, чтобы определить, какой пациент «ПЕРВЫЙ».

Скорее всего, вам удастся изменить повешение на «КАЖДЫЙ пациент» и устранить USE-INDEX. (Возможно, вам понадобится добавить некоторую логику с использованием таких функций, как FIRST-OF и т. Д. Внутри блока, в результате я не могу сказать, что мало что известно о ваших индексах.)

Часть «КАЖДЫЙ элемент» запрос будет потенциально использовать разные индексы, потому что у вас есть разные наборы полей с совпадением равенства. Такие совпадения управляют первой частью алгоритма выбора индекса. В сочетании с поведением FOR FIRST у вас есть много scop для разных возможных заказов сортировки.

+0

Благодарим вас за ввод. Единственный другой индекс для Item: Comp, Method, BatchNum. И есть много индексированных для таблицы пациентов, но первичный уникальный называется PatID: Comp, ID. Из-за этого должно быть только 1 пациент, возвращенный независимо, это порядок предметов для этого пациента, который меняет порядок, я должен был быть более ясным, возможно. Редактировать - Я пробовал ваши предложения, но результаты остались прежними. – user1871734

+0

Если есть только один возможный результат, то не нужно указывать индекс с помощью USE-INDEX, и нет смысла использовать FIRST. –

+0

Я могу согласиться, что это ошибки, которые я забыл. Но я все еще не уверен, почему они обеспечивают два разных результата. Я просто попробовал проверить это в другой копии базы данных, и оба результата вышли, как ожидалось, в правильном порядке. Между этими двумя экземплярами базы данных нет различий в индексах. – user1871734

0

Прогресс определяет лучший индекс для использования на основе операторов WHERE и BREAK. Изменение этих параметров может изменить используемый индекс и изменить порядок записей. Если вы используете динамический запрос, вы можете увидеть, какой индекс Progress был выбран с атрибутом INDEX-INFORMATION.

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. 
+0

Я использовал инструкцию «COMPILE XREF », в которой говорилось, что я использовал индексы, как указано для таблиц «Элемент» и «Пациент» над кодом примера в моем вопросе. Неправильно сортируемое поле Item.Amt не содержит никаких индексов, и все значения индекса одинаковы для записей (4). – user1871734

 Смежные вопросы

  • Нет связанных вопросов^_^