Я опускаю «Описание» на данный момент, потому что это добавляет немного сложности (и может быть лучше подходит для отчета в любом случае):
Первый
CREATE VIEW qryDates
AS
SELECT DISTINCT T1.DealID,
T1.DateEffective AS tblDeals_DateEffective,
(
SELECT MAX(T2.DateEffective)
FROM tblDealItems AS T2
WHERE T1.DealID = T2.DealID
AND T2.DateEffective <= T1.DateEffective
) AS tblDealItems_DateEffective
FROM tblDeals AS T1;
Второе:
CREATE VIEW qryDates2
AS
SELECT DISTINCT T2.DealID,
T2.DateEffective AS tblDealItems_DateEffective,
(
SELECT MAX(T1.DateEffective)
FROM tblDeals AS T1
WHERE T1.DealID = T2.DealID
AND T1.DateEffective <= T2.DateEffective
) AS tblDeals_DateEffective
FROM tblDealItems AS T2
Тогда
SELECT T2.DateEffective AS [Date], '' AS Description,
T1.DealName, T1.AssetClassID,
T2.CategoryID, T2.ParticipantID, T2.Amount
FROM (
tblDeals AS T1
INNER JOIN
qryDates2 AS Q2
ON T1.DateEffective = Q2.tblDeals_DateEffective
AND T1.DealID = Q2.DealID
)
INNER JOIN tblDealItems AS T2
ON T2.DateEffective = Q2.tblDealItems_DateEffective
AND T2.DealID = Q2.DealID
UNION
SELECT T1.DateEffective AS [Date], '' AS Description,
T1.DealName, T1.AssetClassID,
T2.CategoryID, T2.ParticipantID, T2.Amount
FROM (
tblDeals AS T1
INNER JOIN
qryDates AS Q1
ON T1.DateEffective = Q1.tblDeals_DateEffective
AND T1.DealID = Q1.DealID
)
INNER JOIN tblDealItems AS T2
ON T2.DateEffective = Q1.tblDealItems_DateEffective
AND T2.DealID = Q1.DealID;
Качество данных в вашей выборке хорошее: в действительности объединения могут быть внешними, чтобы компенсировать неверные данные. Обратите внимание, что ваша таблица tblDeals
не полностью нормирована (подсказка: DealName
повторяется).
Примечание:
Очевидно, что если я соединю две таблицы на их общем ключе, я получу таблицу
с двенадцатью рядами (3 * 4) вместо шести рядов, которые описывают
история.
вы можете получить набор уникальных дат для каждой сделки, используя UNION
:
SELECT DealID, DateEffective
FROM tblDeals
UNION
SELECT DealID, DateEffective
FROM tblDealItems;
Вот репродукция: создает новую mdb во временной папке, создает таблицы и представления (примечание CREATE VIEW
работает в Access;), добавляет тестовые данные (в соответствии с вопросом), затем выполняет запрос и показывает результаты в окне сообщения; ссылки не требуются, просто скопируйте + вставьте в любой модуль VBA, например. использовать новую книгу Excel:)
Sub NickNick2()
On Error Resume Next
Kill Environ$("temp") & "\DropMe.mdb"
On Error GoTo 0
Dim cat
Set cat = CreateObject("ADOX.Catalog")
With cat
.Create _
"Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & _
Environ$("temp") & "\DropMe.mdb"
With .ActiveConnection
Dim Sql As String
Sql = "CREATE TABLE tblDeals (DealID INT, DealName VARCHAR(100), AssetClassID INT, DateEffective DATETIME, DateEnd DATETIME);"
.Execute Sql
Sql = "CREATE TABLE tblDealItems (DealItemID INT, DealID INT, CategoryID INT, ParticipantID INT, Amount INT, DateEffective DATETIME, DateEnd DATETIME);"
.Execute Sql
Sql = _
" CREATE VIEW qryDates " & _
" AS " & _
" SELECT DISTINCT T1.DealID, " & _
" T1.DateEffective AS tblDeals_DateEffective, " & _
" ( " & _
" SELECT MAX(T2.DateEffective) " & _
" FROM tblDealItems AS T2 " & _
" WHERE T1.DealID = T2.DealID " & _
" AND T2.DateEffective <= T1.DateEffective " & _
" ) AS tblDealItems_DateEffective " & _
" FROM tblDeals AS T1;"
.Execute Sql
Sql = _
" CREATE VIEW qryDates2 " & _
" AS " & _
" SELECT DISTINCT T2.DealID, " & _
" T2.DateEffective AS tblDealItems_DateEffective, " & _
" ( " & _
" SELECT MAX(T1.DateEffective) " & _
" FROM tblDeals AS T1 " & _
" WHERE T1.DealID = T2.DealID " & _
" AND T1.DateEffective <= T2.DateEffective " & _
" ) AS tblDeals_DateEffective " & _
" FROM tblDealItems AS T2;"
.Execute Sql
Sql = _
"INSERT INTO tblDeals VALUES (3, 'Deal 3', 3, '2010-01-01 00:00:00', '2011-07-01 00:00:00');"
.Execute Sql
Sql = _
"INSERT INTO tblDeals VALUES (3, 'Deal 3', 2, '2011-07-01 00:00:00', '2011-10-01 00:00:00');"
.Execute Sql
Sql = _
"INSERT INTO tblDeals VALUES (3, 'Deal 3', 1, '2011-10-01 00:00:00', NULL);"
.Execute Sql
Sql = _
"INSERT INTO tblDealItems VALUES (13, 3, 3, 2, 1500, '2010-01-01 00:00:00', '2011-06-01 00:00:00');"
.Execute Sql
Sql = _
"INSERT INTO tblDealItems VALUES (13, 3, 1, 2, 1500, '2011-06-01 00:00:00', '2011-06-06 00:00:00');"
.Execute Sql
Sql = _
"INSERT INTO tblDealItems VALUES (13, 3, 1, 2, 6000, '2011-06-06 00:00:00', '2011-09-01 00:00:00');"
.Execute Sql
Sql = _
"INSERT INTO tblDealItems VALUES (13, 3, 3, 2, 6000, '2011-09-01 00:00:00', NULL);"
.Execute Sql
Sql = _
"SELECT T2.DateEffective AS [Date], '' AS Description, " & _
" T1.DealName, T1.AssetClassID, " & _
" T2.CategoryID, T2.ParticipantID, T2.Amount " & _
" FROM ( " & _
" tblDeals AS T1 " & _
" INNER JOIN " & _
" qryDates2 AS Q2 " & _
" ON T1.DateEffective = Q2.tblDeals_DateEffective " & _
" AND T1.DealID = Q2.DealID " & _
" ) " & _
" INNER JOIN tblDealItems AS T2 " & _
" ON T2.DateEffective = Q2.tblDealItems_DateEffective " & _
" AND T2.DealID = Q2.DealID " & _
"UNION " & _
"SELECT T1.DateEffective AS [Date], '' AS Description, " & _
" T1.DealName, T1.AssetClassID, " & _
" T2.CategoryID, T2.ParticipantID, T2.Amount " & _
" FROM ( " & _
" tblDeals AS T1 " & _
" INNER JOIN " & _
" qryDates AS Q1 " & _
" ON T1.DateEffective = Q1.tblDeals_DateEffective " & _
" AND T1.DealID = Q1.DealID " & _
" ) "
Sql = Sql & _
" INNER JOIN tblDealItems AS T2 " & _
" ON T2.DateEffective = Q1.tblDealItems_DateEffective " & _
" AND T2.DealID = Q1.DealID " & _
" ORDER " & _
" BY 1;"
Dim rs
Set rs = .Execute(Sql)
MsgBox rs.GetString
End With
Set .ActiveConnection = Nothing
End With
End Sub