2 Consulta SQL variável para dados de um ano anterior

2 Consulta SQL variável para dados de um ano anterior

Tenha uma tabela com IDs atribuídos aos registros à medida que são criados.

Tenha registros de vários anos (às vezes os anos são ignorados, então poderia ter sido: 2019, 2017, 2016, etc...).

Os registros incluem um campo Ano como texto e um campo Nome como texto (este campo Nome é idêntico ao longo dos anos) e um campo AptDate como Data.

Com uma consulta SQL do Access gostaria de mostrar:

o Nome, o Ano atual, o AptDate do ano atual, o AptDate do ano 'anterior' (sendo o Nome idêntico e o Ano sendo o próximo ano mais recente)

Chegamos até aqui com SQL (mostra o AptDate do ano 'anterior' para um EnteredSampleName):

SELECT Table.AptDate
FROM Table
WHERE (((Table.Name)=[EnteredSampleName]) AND ((Year=(SELECT Max(Table.Year) AS LastYear
FROM Table
WHERE (((Table.Year)<(SELECT MAX(Table.Year) FROM Table WHERE ((Table.Name)=[EnteredSampleName]))))))));

Gostaria de remover EnteredSampleName e mostrar este AptDate 'anterior' para todos os registros (alguns anos 'anteriores' podem ser nulos, pois pode não haver nenhum registro anterior para este nome).

Não consigo quebrar essa noz - qualquer ajuda será muito apreciada.


Obrigado por suas respostas úteis - irei testá-las em breve.

Enquanto isso, para responder ao pedido de Lee:

A tabela de amostra tem a seguinte aparência:

ID  Name    Year    AptDate
1   A   2015    2015-02-02
2   B   2015    2015-03-05
3   C   2017    2017-04-04
4   B   2017    2017-06-09
5   C   2018    2018-07-03
6   A   2018    2018-09-10
7   A   2019    2019-01-08
8   D   2019    2019-01-09

Meta do resultado da consulta:

Name    Year    AptDate AptDatePrevious
A   2019    2019-01-08  2018-09-10
B   2017    2017-06-09  2015-03-05
C   2018    2018-07-03  2017-04-04
D   2019    2019-01-09  

Não há AptDatePrevious para D como esperado - espero que esclareça - obrigado.

Responder1

Os exemplos numerados deste site da MS podem indicar a direção certa:
https://support.office.com/en-us/article/nest-a-query-inside-another-query-or-in-an-expression-by-using-a-subquery-a8532322-e42f-4f94- bc38-ace7c182916a

O que você precisará fazer é algo assim:

Selecione Table.Name, Table.Year, Table.AptDate, expr(calcular a data anterior aqui*)
em Table
Order por {como quiser}

*A expressão seria mais ou menos assim:

Selecione max(PrevAptDate.AptDate
da tabela como PrevAptDate
onde (PrevAptDate.AptDate <Table.AptDate)
e
(PrevAptDate.Name = Table.Name)

Isso tudo é improvisado, mas deve estar próximo e apontar na direção certa. Espero que ajude.

Responder2

Supondo que entendi corretamente sua configuração e requisitos, abaixo está um método possível usando junções em vez de subconsultas correlacionadas:

select t0.name, t0.year, t0.aptdate, q2.aptdate
from YourTable t0 left join
(
    select t1.name, t1.aptdate
    from YourTable t1 inner join
    (
        select t2.name, max(t2.year) as lastyear
        from YourTable t2
        where t2.year < year(date())
        group by t2.name
    ) q1 on
    t1.name = q1.name and 
    t1.year = q1.lastyear
) q2 on 
t0.name = q2.name
where t0.year = year(date())

Na consulta acima, substitua cada ocorrência YourTablepelo nome da sua tabela.

Aqui, a consulta mais interna q2obtém o maior yearpara cada um nameonde yearé menor que o ano atual year(date()).

O resultado desta consulta é então unido internamente à tabela original para selecionar o correspondente aptdatepara cada name& máximo year. Isso forma a subconsulta q2.

Finalmente, a tabela original éesquerdaassociado à subconsulta q2(caso não haja registro do ano anterior para um determinado nome) e os resultados são gerados pela consulta pai.

informação relacionada