Usuário com melhor resposta
Selecionar maior data

Pergunta
-
Oi Galera,
Tenho uma tabela de de compras onde tenho a data da compra e o Id do cliente.
Como faço para selecionar somente a data mais recente de cada cliente, mesmo se um cliente tiver 100 registros, quero trazer só a ultima data ( que será a maior) e o id do cliente?
Valeu.
Respostas
-
Boa Tarde,
De fato fiquei devendo o GROUP BY. Tente o seguinte:
Code Snippet-- Se todos os veículos tiverem posições
SELECT
VEC.IDVEICULO, VEC.PLACA, VEC.ANO, VEC.COR,MAX
(DATAEVENTO) AS UltimaPosicaoFROM
Veiculos AS VECINNER
JOIN Posicoes AS POS ON VEC.IDVeiculo = POS.IDVeiculoWHERE
VEC.IDCliente = 27GROUP
BY VEC.IDVEICULO, VEC.PLACA, VEC.ANO, VEC.COR-- Se houver veículos que não necessariamente tem posições
SELECT
VEC.IDVEICULO, VEC.PLACA, VEC.ANO, VEC.COR,MAX
(DATAEVENTO) AS UltimaPosicaoFROM
Veiculos AS VECLEFT
JOIN Posicoes AS POS ON VEC.IDVeiculo = POS.IDVeiculoWHERE
VEC.IDCliente = 27GROUP
BY VEC.IDVEICULO, VEC.PLACA, VEC.ANO, VEC.COR[ ]s,
Gustavo
Todas as Respostas
-
-
-
Boa Tarde,
Acho difícil do código do Ari estar errado a menos que haja códigos de clientes parecidos (ex: 'CLI1', 'CLI1 '). Em todo caso, tente o seguinte código:
Code SnippetSELECT
Cli.IDCliente,(
SELECT MAX(DataCompra) FROM tblCompras AS CompWHERE
Cli.IDCliente = Comp.IDCliente) AS MaiorCompraFROM
(
SELECT DISTINCT IDCliente FROM tblCompras) AS Cli[ ]s,
Gustavo
-
-
-
Insira também na sua clausula FROM, após o IDCliente - , DataCompra
Ela também precisa entrar na especificação de DISTINCT
Você deve verificar também o seguinte: Um cliente pode ter duas compras na mesma data!!! O que poderia apresentar duplicação de dados caso você não especifique algum campo diferente, como por exemplo, HoraCompra.
Insira então também o DISTINCT se necessário, na segunda linha: SELECY DISTINCT MAX(.................
Caso contrário, segue exemplo
SELECT Cli.IDCliente,
(SELECT MAX(DataCompra) FROM tblCompras AS Comp
WHERE
Cli.IDCliente = Comp.IDCliente) AS MaiorCompraFROM
(
SELECT DISTINCT IDCliente, DataCompra FROM tblCompras) AS CliAbraço!
-
Bom Dia,
A coluna DataCompra é dispensável no DISTINCT uma vez que você está recuperando a data da compra na subquery com o MAX(Compra). Colocá-la na consulta irá trazer um resultado indesejável e dispendioso.
Como o DISTINCT será com o IDCliente e o DataCompra, o IDCliente irá se repetir, pois, existirão várias compras para um mesmo cliente. Se ele se repetir na tabela derivada, quando consultarmos no SELECT mais externo, teremos repetições para o IDCliente e o MAX(Compra) para cada uma dessas repetições. Se o DISTINCT trouxer por exemplos três vezes o cliente 1 (uma para cada data), o SELECT mais externo retornará o cliente 1 três vezes e fará o MAX(Compra) três vezes.
Fiz essa consulta mais por desencargo, mas acho que a consulta do ARI já está correta, uma vez que GROUP BY já é um DISTINCT nato e elimina repetições.
[ ]s,
Gustavo
-
Fala galera,
Vamos fazer assim, vou colocar um exemplo pratico de onde preciso usar essa select e vou colocar a estrutura das tabelas.
Meu sistema tem 3 tabelas VEICULOS, CLIENTES e POSICOES abaixo segue a estrutura das tabelas.
CREATE
TABLE [dbo].[VEICULOS]([IDVEICULO] [int]
NOT NULL,[PLACA] [nvarchar]
(8) NULL,[ANO] [nvarchar]
(4) NULL,[COR] [nvarchar]
(30) NULL,[IDCLIENTE] [int]
NULL, CONSTRAINT [PK_VEICULOS] PRIMARY KEY CLUSTERED(
CREATE
TABLE [dbo].[CLIENTES]([IDCLIENTE] [int]
NOT NULL,[NOME] [nvarchar]
(50) NULL,[ENDERECO] [nvarchar]
(50) NULL,[CIDADE] [nvarchar]
(25) NULL,[CEP] [nvarchar]
(11) NULL,[ESTADO] [nvarchar]
(2) NULL,[EMAIL] [nvarchar]
(100) NULL, CONSTRAINT [PK_CLIENTE] PRIMARY KEY CLUSTERED(
CREATE
TABLE [dbo].[GSTB_HISTORICO]([IDPOSICAO] [int]
IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,[IDVEICULO] [int]
NULL,[LOCAL] [nvarchar]
(10) NULL,[DATAATUAL] [datetime]
NULL,[DATAEVENTO] [datetime]
NULL,)
ON [PRIMARY]Cada cliente pode ter vários veículos, e cada veículos pode ter várias posições.
Preciso selecionar a última posição de todos os veículos de um cliente por exemplo ID=27.
A última posição é a que tiver o campo DATAEVENTO maior.
Como faço isso?
Valeu.
-
-
Boa Tarde,
Verifique se o SELECT abaixo o atende:
Code Snippet-- Se todos os veículos tiverem posições
SELECT
VEC.*, MAX(DATAEVENTO) AS UltimaPosicaoFROM
Veiculos AS VECINNER
JOIN Posicoes AS POS ON VEC.IDVeiculo = POS.IDVeiculoWHERE
VEC.IDCliente = 27-- Se houver veículos que não necessariamente tem posições
SELECT
VEC.*, MAX(DATAEVENTO) AS UltimaPosicaoFROM
Veiculos AS VECLEFT
JOIN Posicoes AS POS ON VEC.IDVeiculo = POS.IDVeiculoWHERE
VEC.IDCliente = 27[ ]s,
Gustavo
-
Oi Gustavo, da esse erro:
Msg 8118, Level 16, State 1, Line 3
Column 'VEC.IDVEICULO' is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause.
Msg 8118, Level 16, State 1, Line 3
Column 'VEC.IDENTIFICACAO' is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause.
Msg 8118, Level 16, State 1, Line 3
Column 'VEC.PLACA' is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause.
Msg 8118, Level 16, State 1, Line 3
-
-
Boa Tarde,
De fato fiquei devendo o GROUP BY. Tente o seguinte:
Code Snippet-- Se todos os veículos tiverem posições
SELECT
VEC.IDVEICULO, VEC.PLACA, VEC.ANO, VEC.COR,MAX
(DATAEVENTO) AS UltimaPosicaoFROM
Veiculos AS VECINNER
JOIN Posicoes AS POS ON VEC.IDVeiculo = POS.IDVeiculoWHERE
VEC.IDCliente = 27GROUP
BY VEC.IDVEICULO, VEC.PLACA, VEC.ANO, VEC.COR-- Se houver veículos que não necessariamente tem posições
SELECT
VEC.IDVEICULO, VEC.PLACA, VEC.ANO, VEC.COR,MAX
(DATAEVENTO) AS UltimaPosicaoFROM
Veiculos AS VECLEFT
JOIN Posicoes AS POS ON VEC.IDVeiculo = POS.IDVeiculoWHERE
VEC.IDCliente = 27GROUP
BY VEC.IDVEICULO, VEC.PLACA, VEC.ANO, VEC.COR[ ]s,
Gustavo
-
-
-
Oi Fernando,
Acho que agora eu entendi sua dúvida e por que você fala das supostas repetições.
Vamos ver se eu entendi mesmo. Tente o código abaixo:
Code SnippetSELECT
Q.*, POS.* FROM(
SELECT VEC.IDVEICULO, VEC.PLACA, VEC.ANO, VEC.COR,MAX
(DATAEVENTO) AS UltimaDataFROM
Veiculos AS VECINNER
JOIN Posicoes AS POS ON VEC.IDVeiculo = POS.IDVeiculoWHERE
VEC.IDCliente = ?GROUP
BY VEC.IDVEICULO, VEC.PLACA, VEC.ANO, VEC.COR) AS QINNER
JOIN POSICOES AS POSON
Q.IDVeiculo = POS.IDVeiculo AND Q.UltimaData = POS.DataAtual[ ]s,
Gustavo
-
Oi Gustavo,
Estamos quase lá.
Usei essa query
SELECT
Q.*, POS.* FROM(
SELECT VEC.IDVEICULO,MAX
(DATAEVENTO) AS UltimaDataFROM
VEICULOS AS VECINNER
JOIN POSICOES AS POS ON VEC.IDVeiculo = POS.IDVeiculoWHERE
VEC.IDCliente = 28GROUP
BY VEC.IDVEICULO) AS QINNER
JOIN POSICOES AS POSON
Q.IDVeiculo = POS.IDVeiculo AND Q.UltimaData = POS.DATAEVENTODa tabela veículos eu preciso só a placa o resto não me interessa, e com essa sua select tá retornando as placas erradas, o IDVEICULO retornado não bate com a PLACA.
E tem mais um lance acontecendo, percebi que a tabela POSICOES tem registros duplicados, tem como filtrar para não trazer os duplicados?
Valeu.