Запрос самых последних записей в MS Access на основе даты, указанной в поле формы - PullRequest
0 голосов
/ 15 января 2019

Позвольте мне начать с того, что я провел несколько дней в поисках S.O. и не смогли найти решение. Я заранее прошу прощения, если решение очень простое, но я все еще учусь и ценю любую помощь, которую я могу получить.

У меня есть база данных MS Access 2010, и я пытаюсь создать набор запросов для информирования других форм и запросов. Существует две таблицы: контактная информация заемщика (BC_Info) и основные финансовые показатели (BF_Indicators). Каждый месяц я проверяю и отслеживаю ключевые показатели эффективности каждого заемщика. Я хотел бы создать запрос, который будет предоставлять самую последнюю запись на основе ввода в текстовое поле (формы! [Меню портфолио]! Текст47).

Два соображения отделили это от других постов, которые я видел в теге "great-n-per-group":

  1. Не каждый заемщик будет иметь данные за каждый месяц.
  2. Мне нужно иметь возможность посмотреть в прошлое, т.е. если это 1 января 2019 года, и я хочу увидеть показатели по состоянию на 31 июля 2017 года, я хочу сделать уверен, что я вижу только данные до 31 июля 2017 года, но как можно ближе к эта дата возможна.

Поля следующие:

BC_Info - BorrowerName -PartnerID

BF_Indicators -Fin_ID -DateUpdated

Таблицы связаны с BorrowerName - уникальным соглашением об именах, используемым для первичного ключа BC_Info.

Что у меня сейчас есть:

SELECT BCI.BorrowerName, BCI.PartnerID, BFI.Fin_ID, BFI.DateUpdated
FROM ((BC_Info AS BCI
    INNER JOIN  BF_Indicators AS BFI
        ON BFI.BorrowerName = BCI.BorrowerName)
    INNER JOIN
    (
        SELECT Fin_ID, MAX(DateUpdated) AS MAX_DATE
        FROM BF_Indicators
        WHERE (DateUpdated <= Forms![Portfolio_Review Menu]!Text47 OR
        Forms![Portfolio_Review Menu]!Text47 IS NULL)
        GROUP BY Fin_ID
    ) AS Last_BF ON BFI.Fin_ID = Last_BF.Fin_ID AND
        BFI.DateUpdated = Last_BF.MAX_DATE);

Это дает мне поля, которые мне нужны, и будет хранить записи, которые не соответствуют дате, указанной в текстовом поле, но будут выдавать все записи до ввода текстового поля, а не только самые последние.

Результаты (Дата ввода: 31.12.2008; MEHN-45543 является только Заемщиком с информацией позднее, чем 30.09.2008):

BorrowerName    PartnerID   Fin_ID  DateUpdated 
 MEHN-45543         19         9    12/31/2018 
 ARYS-7940           5        10     9/30/2018 
 FINS-21032         12        11     9/30/2018
 ELET-00934          9        12     9/30/2018
 MEHN-45543         19        18     9/30/2018

Ожидаемые результаты (дата ввода - 12/31/2018; MEHN-45543 является только Заемщиком с информацией позднее, чем 30.09.08):

BorrowerName    PartnerID   Fin_ID  DateUpdated 
 MEHN-45543         19         9    12/31/2018 
 ARYS-7940           5        10     9/30/2018 
 FINS-21032         12        11     9/30/2018
 ELET-00934          9        12     9/30/2018

Как уже упоминалось, я планирую использовать результаты этого запроса для генерации дальнейших запросов, которые используют агрегированную информацию из финансовых показателей для определения качества портфеля в данный момент.

Пожалуйста, дайте мне знать, если есть какая-либо другая информация, которую я могу предоставить. И еще раз, спасибо заранее.

1 Ответ

0 голосов
/ 16 января 2019

Попробуйте присоединить BC_Info к запросу, который агрегирует BF_Indicators для BorrowerName, а не Fin_ID. Протестировано с буквальным значением даты:

SELECT BC_Info.*, MaxDate 
FROM BC_Info 
INNER JOIN
(SELECT BorrowerName, Max(DateUpdated) AS MaxDate 
 FROM BF_Indicators WHERE DateUpdated <=#12/31/2018# GROUP BY BorrowerName) AS Q1 
ON BC_Info.BorrowerName=Q1.BorrowerName;

Если вам нужно включить Fin_ID в результаты, то:

SELECT BC_Info.*, Fin_ID, DateUpdated FROM BC_Info 
INNER JOIN
(SELECT * FROM BF_Indicators WHERE Fin_ID IN 
    (SELECT TOP 1 Fin_ID FROM BF_Indicators AS Dupe 
     WHERE Dupe.BorrowerName=BF_Indicators.BorrowerName AND DateUpdated<=#12/31/2018# 
     ORDER BY Dupe.DateUpdated DESC)
) AS Q1
ON BC_Info.BorrowerName = Q1.BorrowerName;

Если вам не нравится TOP N, настройте исходный запрос:

SELECT BCI.BorrowerName, BCI.PartnerID, BFI.Fin_ID, BFI.DateUpdated
FROM ((BC_Info AS BCI
    INNER JOIN  BF_Indicators AS BFI
        ON BFI.BorrowerName = BCI.BorrowerName)
    INNER JOIN
    (
        SELECT BorrowerName, MAX(DateUpdated) AS MAX_DATE
        FROM BF_Indicators
        WHERE (DateUpdated <= #12/31/2018#)
        GROUP BY BorrowerName
    ) AS Last_BF ON BFI.BorrowerName = Last_BF.BorrowerName AND
        BFI.DateUpdated = Last_BF.MAX_DATE);

И еще один вопрос:

SELECT BC_Info.PartnerID, BC_Info.BorrowerName, BF_Indicators.Fin_ID, BF_Indicators.DateUpdated
FROM BC_Info RIGHT JOIN BF_Indicators ON BC_Info.BorrowerName = BF_Indicators.BorrowerName
WHERE (((BF_Indicators.DateUpdated)=DMax("DateUpdated","BF_Indicators","BorrowerName='" & [BC_Info].[BorrowerName] & "' AND DateUpdated<=#12/31/2018#")));
...