РЕДАКТИРОВАТЬ: Мой предыдущий ответ был ерундой. Теперь это полная перезапись
На самом деле это проблема, которая мучила меня всю жизнь в SQL. Решение, которое я собираюсь дать вам, чертовски грязное, но оно работает, и я был бы признателен любому, кто сказал бы: «Да, это чертовски грязно, но это единственный способ сделать это» или сказать «нет, сделайте это ... ».
Я думаю, что беспокойство происходит от присоединения к двум датам. То, как это происходит здесь, не является проблемой, так как они будут точно соответствовать (у них точно такие же корневые данные), но все равно это не так ...
В любом случае, если разбить это, вам нужно сделать это в два этапа.
1) Во-первых, нужно вернуть набор результатов [AID], [самое раннее CreationTime], предоставляя вам самое раннее время создания для каждого AID.
2) Затем вы можете использовать latestCreationTime, чтобы получить CID, который вы хотите.
Так что для части (1) я бы лично создал представление, чтобы сделать это просто, чтобы держать вещи в порядке. Это позволяет вам протестировать эту часть и заставить ее работать, прежде чем объединить ее с другими компонентами.
create view LatestCreationTimes
as
select b.AID,
max(c.CreationTime) LatestCreationTime
from TableB b,
TableC c
where b.CID = c.CID
group by b.AID
Обратите внимание, на данный момент мы не учли статус.
Затем вам нужно присоединить это к TableA (для получения статуса) и TableB и TableC (для получения CID). Вам нужно сделать все очевидные ссылки (AID, CID), а также присоединить столбец LatestCreationTime в представлении к столбцу CreationTime в TableC. Не забудьте также присоединиться к представлению AID, в противном случае, когда две записи были созданы одновременно для разных записей A, возникнут проблемы.
select A.AID,
C.CID
from TableA a,
TableB b,
TableC c,
LatestCreationTimes lct
where a.AID = b.AID
and b.CID = c.CID
and a.AID = lct.AID
and c.CreationTime = lct.LatestCreationTime
and a.STATUS = 'OK'
Я уверен, что это работает - я проверил, настроил данные, перепроверил, и он ведет себя. По крайней мере, он делает то, что, как я считаю, должен делать.
Однако это не касается возможности двух одинаковых CreationTimes в таблице C для одной и той же записи. Я предполагаю, что этого не должно произойти, если только вы не написали когда-нибудь, что абсолютно ограничивает это, это нужно учитывать.
Для этого мне нужно сделать предположение о том, какой из них вы бы предпочли. В этом случае я собираюсь сказать, что если есть два идентификатора CID, которые соответствуют друг другу, вы бы предпочли более высокий (он, скорее всего, более актуален).
select A.AID,
max(C.CID) CID
from TableA a,
TableB b,
TableC c,
LatestCreationTimes lct
where a.AID = b.AID
and b.CID = c.CID
and c.CreationTime = lct.LatestCreationTime
and a.STATUS = 'OK'
group by A.AID
И это, я считаю, должно работать для вас. Если вы хотите, чтобы это был один запрос, а не представление, тогда:
select A.AID,
max(C.CID) CID
from TableA a,
TableB b,
TableC c,
(select b.AID,
max(c.CreationTime) LatestCreationTime
from TableB b,
TableC c
where b.CID = c.CID
group by b.AID) lct
where a.AID = b.AID
and b.CID = c.CID
and c.CreationTime = lct.LatestCreationTime
and a.STATUS = 'OK'
group by A.AID
(я только что встроил представление в запрос, в противном случае принципал точно такой же).