2017-06-12 1 views
3

Je dois retourner le premier enregistrement pour chaque ID d'étudiant distinct. Dans mon exemple de code, j'ai un enregistrement avec deux incidents à la même date, et un autre étudiant avec plusieurs incidents à des dates différentes.Comment puis-je retourner l'enregistrement avec la date la plus proche?

Je dois sélectionner la date la plus proche, et s'il y en a plusieurs à la même date, alors l'ID d'incident le plus tôt comme critère suivant. Quel est un bon moyen de le faire?

J'ai environ 35 colonnes dans cet ensemble de données, mais seulement inclus les 5 premiers ci-dessous pour la brièveté.

données:

Picture of data

Résultats souhaités:

Picture of desired results

L'exemple de code est ci-dessous.

CREATE TABLE #TEMP (
    StudentID float, 
    SchoolID float, 
    StudentNameFull nvarchar(255), 
    IncidentID float, 
    IncidentDate date 
) 

    INSERT INTO #TEMP (StudentID, SchoolID, StudentNameFull, IncidentID, IncidentDate) 
    VALUES 
    (1111111, 406, 'Smith,John', 123321, '20170501'), 
    (1111111, 406, 'Smith,John', 123322, '20170501'), 
    (2222222, 406, 'Jones,Tim', 654789, '20170501'), 
    (2222222, 406, 'Jones,Tim', 659872, '20170503'), 
    (2222222, 406, 'Jones,Tim', 478978, '20170508') 

    SELECT * FROM #TEMP 

Merci.

Répondre

6

Dans SQL Server, vous pouvez le faire en utilisant ROW_NUMBER():

select t.* 
from (select t.*, 
      row_number() over (partition by StudentId order by IncidentDate, IncidentID) as seqnum 
     from #TEMP t 
    ) t 
where seqnum = 1; 

Cette interprète « plus facile incident "comme" incidentId avec la plus petite valeur ".

+1

Merci @Gordon Linoff, voulez-vous dire "incident le plus tôt"? – JM1

+1

Je préfère faire ces choses avec 'DENSE_RANK' plutôt qu'avec' ROW_NUMBER'. S'il y a une égalité, ROW_NUMBER ne sélectionnera qu'un seul enregistrement, alors que DENSE_RANK sélectionnera les deux (ou plus). Même dans des cas comme celui-ci, où les liens ne sont probablement pas attendus, je veux savoir s'ils se produisent. – HoneyBadger

+0

Merci @HoneyBadger, la syntaxe serait-elle similaire? Remplacez simplement Row_Number par Dense_Rank? – JM1

5

Vous pouvez utiliser le avec des liens clause de concert avec ROW_NUMBER()

SELECT Top 1 with Ties * 
    FROM #TEMP 
    Order By Row_Number() over (Partition By StudentID Order by IncidentDate,IncidentID) 
+0

Vous avez oublié de commander également par 'IncidentId' ... vérifiez les données de près. –

+0

@TimBiegeleisen Merci pour la capture –

+0

Quel genre de logique c'est ... +1 pour une nouvelle façon de faire .. –