Мне нужно вернуть все заполненные родительские элементы из моей таблицы PARENTS, когда они были завершены в пределах диапазона дат.Все действия против родителя хранятся в дочерней таблице PARENT_ACTIONS. Трудность, с которой я столкнулся, заключается в том, что после завершенного действия может быть больше действий или даже несколько выполненных действий, сохраненных для этого PARENT_ID, и мне нужно только, чтобы родитель возвращался, еслиМаксимальное действие - это завершенное действие, и оно попадает в выбранный пользователем диапазон дат.
Я попытался выполнить поиск по форумам, но большая часть того, что я нашел, было «как найти максимальную дату дочерней записи для родительской записи», что было полезно в том, как сделать максимум, но неполезно для моей точной проблемы.
Я не помню всего, что я пробовал, но в настоящее время я пытаюсь этот код, который действительно возвращает правильные результаты (11 строк), это занимает всего 10 минут из-заужасно неэффективный SQL.
var parents = (from p in db.PARENTs
where p.PARENT_ACTION
.Any(pa => pa.ACTION_ID == 99
&& pa.ACTION_DATE >= beginDate
&& pa.ACTION_DATE <= endDate
&& pa.ACTION_DATE == p.PARENT_ACTION.Max(pam => pam.ACTION_DATE))
select p);
Я хотел бы написать что-то, что очень похоже на приведенный ниже SQL, который возвращает <1 секунду для 11 строк. </p>
select * from parent p
where p.STATUS = 99
and exists (select 'x' from parent_action pa
where pa.PARENT_ID = p.ID
and pa.ACTION_ID = 99
and pa.ACTION_DATE = (select max(pam.action_date)
from parent_action pam
where pam.parent_id = p.id)
and pa.action_date between to_date('04/10/2019', 'MM/DD/YYYY') and to_date('04/23/2019', 'MM/DD/YYYY'));
***** Обновление 1 *****
Я использую System.Data.Entity для запроса базы данных Oracle 12c
Sample data:
STATUS
ID, DESC
1, ENTERED
2, SUBMITTED
99, COMPLETED
ACTIONS
ID, DESC
1, ENTER
2, SUBMIT
99, COMPLETE
PARENT
ID, STATUS
1, 99
2, 1
3, 99
4, 99
PARENT_ACTIONS
ID, PARENT_ID, ACTION_ID, ACTION_DATE
1, 1, 1, 04/01/2019
2, 1, 2, 04/05/2019
3, 1, 99, 04/11/2019
4, 2, 1, 04/11/2019
5, 3, 1, 04/15/2019
6, 3, 2, 04/16/2019
7, 3, 99, 04/17/2019
8, 3, 2, 04/18/2019 --Parent sent back to submitted status
9, 4, 1, 04/01/2019
10, 4, 2, 04/11/2019
11, 4, 99, 04/15/2019
12, 4, 99, 04/24/2019 --Completion details updated by customer, business rules require a new complete action be written
На основе этих примеров данных с диапазоном дат 4 /С 10/2019 по 23.04.2009 я хочу написать что-то, что будет возвращать ТОЛЬКО родительский идентификатор 1, потому что это единственный родитель с максимальной датой действия, равной 1) завершенному действию (99) и 2) между указаннымдиапазон дат.Я хочу, чтобы родитель 4 был исключен, поскольку максимальная дата действия выходит за пределы указанного диапазона дат.
***** Обновление 2 *****
Похоже, что я делаюиметь правильный код, чтобы вернуть желаемые результаты;Тем не менее, я думал, что делал что-то ужасно неправильно, так как выполнение запроса превысило 10 минут.После дальнейшего расследования выясняется, что я стал еще одной жертвой появления CAST AS в сгенерированном SQL, что резко снизило производительность.В моем случае это приведение моих столбцов идентификаторов в SQL как число (10,0), когда в моей таблице столбцы идентификаторов являются целочисленными, а в моей модели EF столбцы идентификаторов - Int32.Я не совсем уверен, как это исправить, или я должен просто написать свой собственный SQL для этой конкретной потребности данных.