2011-03-24 2 views
6

plusieurs entrées de chaque jour, j'ai une table, quelque chose comme:obtenir seulement dernière ligne dans 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 

Pour résumer le tableau ci-dessus, il y a trois lignes pour jour , et deux rangées pour le jour .

Maintenant, je veux juste sélectionner la dernière ligne - une seule ligne - par jour.
(une rangée de neuf, l'un pour 10 et l'autre pour 11)

I ne peut pas utiliser distinct en raison de l'horodatage. Je ne peux pas grouper et utiliser:

CAST(CONVERT(FLOAT, EnteredOn) AS INT) 

parce que quand je sélectionne le champ EnteredOn, il se plaint que ce n'est pas groupé. Je ne peux pas combiner distinct(cast..date...) parce que je ne peux pas obtenir la bonne syntaxe.

Comment puis-je sélectionner - seulement Nom, EnteredOn, Pourcentage les champs avec distinct pour chaque jour?

merci d'avance.

Répondre

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

Salut, cela fonctionne, cependant, je ne comprends pas la plupart de ce que fait la requête? esp '' partition'' - qu'est-ce que ça fait? cette requête ralentit-elle sur un grand nombre de lignes? merci – iamserious

+0

aussi, cela considère uniquement à ce jour, désolé de ne pas le mentionner avant, je veux être en mesure de filtrer sur la personne aussi. – iamserious

+0

ajouter au dernier commentaire '' sélectionner une rangée par jour d'une personne en particulier et un pourcentage particulier'' - quelque chose comme ça .. – iamserious

8

1 rang/jour:

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 rang/personne/jour:

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

Salut @manji, shou ldn't '' group by clause'' inclut aussi '' Id''? – iamserious

+0

vous avez raison, Id n'a rien à voir avec ce dont vous avez besoin – manji

+0

Merci beaucoup de m'aider :-) – 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

je suggère une autre astuce ici:

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) 
Questions connexes