2011-03-24 14 views
6

Tengo una tabla, algo así como:obtener sólo la última fila de varias entradas de cada día en TSQL

Id  Name  EnteredOn     Percentage 
````````````````````````````````````````````````````````````` 
01  person1  2011-03-09 17:29:35.683  56.29 
02  person1  2011-03-09 17:29:35.731  76.29 
03  person1  2011-03-09 18:15:78.683  56.29 
04  person1  2011-03-10 17:29:35.683  56.29 
05  person1  2011-03-10 16:29:31.683  56.29 
06  person1  2011-03-11 17:29:35.683  56.29 

para resumir la tabla anterior, hay tres filas para días , y dos filas para el día .

Ahora, solo quiero seleccionar la última fila - una sola fila - por día.
(una fila para 9, uno para 10 y el de 11)

no puedo usar distinta debido a la marca de tiempo. No puedo agrupar y usar:

CAST(CONVERT(FLOAT, EnteredOn) AS INT) 

porque cuando selecciono el campo Entrado en, se queja de que no está agrupado. No puedo combinar distinct(cast..date...) porque no puedo obtener la sintaxis correcta.

¿Cómo puedo seleccionar - solo Nombre, ingresado, Porcentaje campos con distinto a cada día?

muchas gracias de antemano.

Respuesta

13
;with cte as 
(
    select 
    *, 
    row_number() over(partition by datediff(d, 0, EnteredOn) order by EnteredOn desc) as rn 
    from YourTable 
) 
select * 
from cte 
where rn = 1 
+0

Hola, esto funciona, sin embargo, no entiendo la mayor parte, ¿qué está haciendo la consulta? esp '' partition'' - ¿qué hace esto? ¿esta consulta se ralentiza en un gran número de filas? gracias – iamserious

+0

también, esto se considera únicamente en fecha, lo siento por no mencionarlo antes, quiero poder filtrar en persona también. – iamserious

+0

añadiendo al último comentario '' seleccionar una fila por cada día de una persona en particular y en particular percentage'' - algo como esto .. – iamserious

8

1 fila/día:

SELECT t1.Name, t1.EnteredOn, t1.Percentage 
    FROM table t1 
    JOIN (SELECT MAX(EnteredOn) Max_EnteredOn_By_Day 
      FROM table 
     GROUP BY convert(varchar, EnteredOn, 112)) t2 
    ON t1.EnteredOn = t2.Max_EnteredOn_By_Day 

1 fila/persona/día:

SELECT t1.Name, t1.EnteredOn, t1.Percentage 
    FROM table t1 
    JOIN (SELECT Name, MAX(EnteredOn) Max_EnteredOn_By_Day 
      FROM table 
     GROUP BY Name, convert(varchar, EnteredOn, 112)) t2 
    ON t1.Name = t2.Name 
AND t1.EnteredOn = t2.Max_EnteredOn_By_Day 
+0

Hola, @manji, shou ldn't '' group by clause'' incluye '' Id'' también? – iamserious

+0

tiene razón, Id no tiene nada que ver con lo que necesita – manji

+0

Muchas gracias por ayudarme :-) – iamserious

6
SELECT Name, EnteredOn, Percentage 
FROM ( SELECT *, ROW_NUMBER() OVER(PARTITION BY CONVERT(VARCHAR(8),EnteredOn,112) ORDER BY EnteredOn DESC) Corr 
     FROM YourTable) A 
WHERE Corr = 1 
2

que sugeriría un truco más aquí:

select top 1 with ties 
    Name, EnteredOn, Percentage 
from YourTable 
order by row_number() over(partition by datediff(d, 0, EnteredOn) order by Name, EnteredOn desc) 
Cuestiones relacionadas