РЕДАКТИРОВАТЬ: мой предыдущий ответ был ерундой. Теперь это полная переработка
На самом деле это проблема, которая беспокоила меня на протяжении всей моей жизни с SQL. Решение, которое я вам дам, чертовски запутано, но оно работает, и я был бы признателен, если бы кто-нибудь сказал: «Да, это чертовски запутано, но это единственный способ сделать это», или сказал: «Нет, сделайте это... ".
Я думаю, беспокойство возникает из-за совмещения двух свиданий. То, как это происходит здесь, не проблема, поскольку они будут точно соответствовать (у них точно такие же корневые данные), но это все равно кажется неправильным...
В любом случае, разбивая это, вам нужно сделать это в два этапа.
1) Первый — вернуть набор результатов [AID], [наиболее раннее время создания], указывающий вам самое раннее время создания для каждого AID.
2) Затем вы можете использовать lastCreationTime, чтобы получить нужный 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
(Я только что встроил представление в запрос, в остальном принцип точно такой же).
person
Jon Hopkins
schedule
30.04.2009