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.AptDateda 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 YourTable
pelo nome da sua tabela.
Aqui, a consulta mais interna q2
obtém o maior year
para cada um name
onde year
é menor que o ano atual year(date())
.
O resultado desta consulta é então unido internamente à tabela original para selecionar o correspondente aptdate
para 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.