Eu tenho uma tabela que é uma entrada de coleção sobre quando um usuário estava conectado.
username, date, value
--------------------------
brad, 1/2/2010, 1.1
fred, 1/3/2010, 1.0
bob, 8/4/2009, 1.5
brad, 2/2/2010, 1.2
fred, 12/2/2009, 1.3
etc..
Como crio uma consulta que me daria a data mais recente para cada usuário?
Atualização: esqueci que precisava ter um valor compatível com a data mais recente.
sql
greatest-n-per-group
cabeça de peixe
fonte
fonte
Respostas:
fonte
max(date)
retornaria uma data que juntaria vários registros). Para evitar esse problema, seria preferível usar a solução da @ dotjoe: stackoverflow.com/a/2411763/4406793 .Usando funções de janela (funciona no Oracle, Postgres 8.4, SQL Server 2005, DB2, Sybase, Firebird 3.0, MariaDB 10.3)
fonte
username
neste caso) e nem sequer exija um campo "ordenável" exclusivo (como juntarmax(date)
outras respostas).order by date desc, id desc)
.Vejo que a maioria dos desenvolvedores usa uma consulta embutida sem considerar seu impacto em grandes dados.
Simplesmente, você pode conseguir isso:
fonte
Para obter a linha inteira que contém a data máxima para o usuário:
fonte
fonte
Pela minha experiência, a maneira mais rápida é pegar cada linha para a qual não há linha mais nova na tabela.
Outra vantagem é que a sintaxe usada é muito simples e que o significado da consulta é bastante fácil de entender (pegue todas as linhas para que não exista nenhuma linha mais nova para o nome de usuário que está sendo considerado).
NÃO EXISTE
ROW_NUMBER
JUNÇÃO INTERNA
JUNTA EXTERNA ESQUERDA
fonte
SELECT username, value FROM t WHERE NOT EXISTS ( SELECT * FROM t AS witness WHERE witness.date > t.date AND witness.username = t.username );
Este deve fornecer o resultado correto para sua pergunta editada.
A subconsulta garante encontrar apenas as linhas da data mais recente e a externa
GROUP BY
cuidará dos vínculos. Quando houver duas entradas para a mesma data para o mesmo usuário, ela retornará a que tiver a mais altavalue
.fonte
Você também pode usar a função de classificação analítica
fonte
Resolveria o problema atualizado. Pode não funcionar tão bem em tabelas grandes, mesmo com boa indexação.
fonte
fonte
Para o Oracle classifica o conjunto de resultados em ordem decrescente e obtém o primeiro registro, para obter o registro mais recente:
fonte
fonte
fonte
Select * from table1 where lastest_date=(select Max(latest_date) from table1 where user=yourUserName)
A Consulta interna retornará a data mais recente do usuário atual. A consulta externa puxará todos os dados de acordo com o resultado da consulta interna.
fonte
Usei dessa maneira para registrar o último registro de cada usuário que tenho na minha mesa. Foi uma consulta para obter o último local para o vendedor, conforme detectado recentemente nos dispositivos PDA.
fonte
fonte
Minha pequena compilação
join
melhor do que aninhadoselect
group by
não fornece oprimary key
que é preferível parajoin
partition by
em conjunto comfirst_value
( docs )Então, aqui está uma consulta:
Prós:
where
instrução usando qualquer colunaselect
quaisquer colunas de linhas filtradasContras:
fonte
Eu fiz um pouco para a minha aplicação, pois:
Abaixo está a consulta:
fonte
Isso é semelhante a uma das respostas acima, mas, na minha opinião, é muito mais simples e organizado. Além disso, mostra um bom uso para a declaração de aplicação cruzada. Para o SQL Server 2005 e superior ...
fonte
fonte
Isso também deve funcionar para obter todas as entradas mais recentes para os usuários.
fonte
Você usaria a função agregada MAX e GROUP BY
fonte
value
, não a associada àMAX(date)
linha.