COMO AGRUPAR?

GUILHERMEMFA 21/03/2014 12:30:57
#436359
Boa tarde pessoal!

Tenho uma tabela com os seguintes campos: (idProduto,precounitario,dataemissao)


idProduto precounitario dataemissao
1 2,20 16/01/2013
1 2,30 22/04/2013
1 2,26 15/03/2014
2 5,65 04/10/2013
2 4,54 07/01/2014
2 6,78 02/02/2014

Preciso de uma consulta que me retorne os dados da data de emissão mais recente por produto.
Ex:

idProduto precounitario dataemissao
1 2,26 15/03/2014
2 6,78 02/02/2014

--> Estou utilizando Sql Sever 2008
Alguém pode me dar uma luz.
Grato
TUNUSAT 21/03/2014 13:19:17
#436365
GUILHERMEMFA,

Utilizei o velho NorthWind para SQL Server. Tabela [Ô]Order Details[Ô]. NÃO tem data disponível, mas tem de valor [Ô]UnitPrice[Ô] ... precisa substituílo pela sua data.
Abaixo duas querys de teste para chegar o resultado.
A terceira e última query é o que você deseja? Por favor, confirme. Se não souber fazer com data eu mont8o sua tabela no meu banco e monto a query para você, okay?


--- INICIO TESTES
select OrderID, count(*) as tam
from [Order Details]
group by OrderID

select *
from [Order Details]
where OrderID = 10248
--- FIM TESTES

--- SOLUÇÃO!
select OrderID, max(UnitPrice)
from [Order Details]
group by OrderID


[][ô]s,
Tunusat.
GUILHERMEMFA 21/03/2014 13:39:16
#436367
Dessa forma não atende, você trabalhou com dois campos em sua query: OrderID, UnitPrice

Se eu fizer isso na isso na minha query ela irá me retornar o valor máximo por Identificador do produto, desconsiderando a data de emissão.

Eu preciso que a query me retorne os dados da ultima emissão com os campos:
- O identificador do produto (IdProduto da última dataemissão);
- Preço Unitário (não é o maior preço e sim o preço da ultima dataemissão)
- Data da emissão (Data da última dataemissão).
TUNUSAT 21/03/2014 14:08:34
#436371
GUILHERMEMFA,

Okay.
Vou a tabela, a massa de teste e depois dou a solução:

-----------------------------------------------------------
-- INICIO DA CRIAÇÃO DA TABELA
-----------------------------------------------------------
CREATE TABLE TESTE
(idProduto INTEGER,
precounitario FLOAT,
dataemissao DATETIME);
-----------------------------------------------------------
-- FIM DA CRIAÇÃO DA TABELA
-----------------------------------------------------------
-- INICIO DA CRIAÇÃO DA MASSA DE TESTES
-----------------------------------------------------------
INSERT INTO TESTE (idProduto, precounitario, dataemissao)
VALUES (1, 1, [ô]2001/01/01[ô])
-----------------------------------------------------------
INSERT INTO TESTE (idProduto, precounitario, dataemissao)
VALUES (1, 2, [ô]2001/01/02[ô])
-----------------------------------------------------------
INSERT INTO TESTE (idProduto, precounitario, dataemissao)
VALUES (2, 2, [ô]2001/01/02[ô])
-----------------------------------------------------------
INSERT INTO TESTE (idProduto, precounitario, dataemissao)
VALUES (3, 1, [ô]2001/01/01[ô])
-----------------------------------------------------------
INSERT INTO TESTE (idProduto, precounitario, dataemissao)
VALUES (1, 2, [ô]2001/01/02[ô])
-----------------------------------------------------------
INSERT INTO TESTE (idProduto, precounitario, dataemissao)
VALUES (3, 1, [ô]2001/01/03[ô])
-----------------------------------------------------------
SELECT * FROM teste
-----------------------------------------------------------
-- FIM DA CRIAÇÃO DA MASSA DE TESTES
-----------------------------------------------------------
-- SOLUÇÃO!
-----------------------------------------------------------
select idProduto, max(dataemissao)
from TESTE
group by idProduto
-----------------------------------------------------------

é isto?

[][ô]s,
Tunusat.
GUILHERMEMFA 21/03/2014 14:30:55
#436379
TUNUSAT, você inseriu os dados perfeitamente, só que no seu select você não exibiu o precounitário da dataemissão mais recente


preciso que me retorne os 3 campos (idProduto,precounitario,dataemissao) no select
TUNUSAT 21/03/2014 16:49:17
#436384
GUILHERMEMFA,

Perai ... vamos conversar.

- Para o código [Ô]1[Ô], preco [Ô]2[Ô] a maior data de emissão é [ô]2001/01/02[ô]
- Para o código [Ô]2[Ô], preco [Ô]2[Ô] a maior iro data de emissão é [ô]2001/01/02[ô] (só tem ele)
- Para o código [Ô]3[Ô], preco [Ô]1[Ô] a maior data de emissão é [ô]2001/01/03[ô]

A query:

----------------------------------------------------------------------
select idProduto, precounitario, max(dataemissao)
from TESTE
group by idProduto, precounitario
----------------------------------------------------------------------

Não serve?
Tipo ... não poderia ter o idProduto dobrado (1 para cada preço unitário).

[][ô]s,
Tunusat.
TUNUSAT 21/03/2014 16:56:51
#436385
GUILHERMEMFA,

No [Ô]Books On Line[Ô] ...

========================================================

It is not legal, however, to have just the expression ColumnB in the select list:

SELECT ColumnA,
ColumnB,
SUM(ColumnC) AS SumC
FROM TableX
GROUP BY ColumnA

Because the GROUP BY can return only one row with a value of 1 in ColumnA, there is no way to return the three values of ColumnB (abc, def, and ghi) associated with the value 1 in ColumnA.

You cannot use GROUP BY or HAVING on ntext,text,image, or bit columns unless they are in a function that returns a value having another data type. Examples of such functions are SUBSTRING and CAST.
========================================================


[][ô]s,
Tunusat.
OCELOT 21/03/2014 17:49:19
#436387
Resposta escolhida
Pelo que pesquisei você pode tentar o seguinte

WITH tmp AS
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY idProduto ORDER BY dataemissao DESC) AS rn FROM SuaTabela
)
SELECT idProduto, precounitario, dataemissao FROM tmp WHERE rn = 1


Basicamente o que esta SQL faz é criar tipo uma tabela temporária (o WITH faz isso) em que se tem uma nova coluna chamada rn que é o número da linha, mas este número e agrupado pelo idProduto, então para cada idProduto diferente a contagem da linha começa do 1, e como ordenamos por dataemissao de forma decrescente, a linha com o rn = 1 vai sempre ser a da maior data de cada produto, então fica faltando apenas filtrar o resultado pela linha que tiver o rn = 1
OMAR2011 21/03/2014 18:32:14
#436391
Acredito que seja mais ou menos assim.
[Ô]Select idproduto,Max(dataemissao)as data From TestData group by idproduto[Ô]
GUILHERMEMFA 25/03/2014 13:28:49
#436502
OCELOT,

realizei os testes no SQL Sever e deu certinho. Porém quando eu transfiro para o VB da forma abaixo:

Dim rsTbTemp As New ADODB.Recordset
Dim sqlTbTemp As String
sqlTbTemp = [Ô]WITH tmp AS (SELECT *, ROW_NUMBER() OVER (PARTITION BY idProduto ORDER BY dataemissao DESC) AS rn FROM SuaTabela) [Ô] & _
[Ô]SELECT idProduto, precounitario, dataemissao FROM tmp WHERE rn = 1[Ô]
rsTbTemp.Open sqlTbTemp, cnBanco


Ocorre o seguinte erro:

Incorrect syntax near the keyword [ô]WITH[ô].

Saberia me dizer onde esta o erro

--> Neste caso em especifico não estou usando Stored Procedure

OCELOT 25/03/2014 15:52:11
#436509
Não sei explicar o porque, mas com o sqloledb aparentemente você precisa colocar um ponto e virgula antes do WITH para ele funcionar, tente mudar oseu código para

sqlTbTemp = [Ô];WITH tmp AS (SELECT *, ROW_NUMBER() OVER (PARTITION BY idProduto ORDER BY dataemissao DESC) AS rn FROM SuaTabela) [Ô] & _
[Ô]SELECT idProduto, precounitario, dataemissao FROM tmp WHERE rn = 1[Ô]
Página 1 de 2 [11 registro(s)]
Tópico encerrado , respostas não são mais permitidas