2009-05-21 7 views
1

Disons que je le tableau de résultat suivant de mon SQL sélectionnez:Unicité sur la base plus grande valeur où pas toutes les cellules sont les mêmes

 
DocumentId  CreationDate  InstanceId 
ABC    10th Jan   0c60f4e2-02fc-4244-9ec5-4d259ea5774d 
ABC    11th Jan   2168ab5d-d6ca-4db3-90f0-b621d72108b8 
BCA    4th Jan   cb7cdf24-b50f-4bd9-b2b5-d58a14793dd8 

Notez que InstanceId est différent pour chaque retour maintenant; C'est essentiellement la clé primaire de la table.

Comment puis-je modifier ma sélection afin que je suis retourné une seule ligne par DocumentId, choisir le « plus récent » (déterminé par CreationDate), en veillant à ce que la InstanceId sur la ligne est correcte.

Ainsi, l'exemple résultats ci-dessus renverrait à la place:

 
DocumentId  CreationDate  InstanceId 
ABC    11th Jan   2168ab5d-d6ca-4db3-90f0-b621d72108b8 
BCA    4th Jan   cb7cdf24-b50f-4bd9-b2b5-d58a14793dd8 

(BTW, désolé pour le titre de la question horrible, ne hésitez pas à changer pour quelque chose de plus approprié)

+1

La syntaxe sera différente en fonction du logiciel base de données que vous utilisez. –

Répondre

1

Exemple pour Oracle: Il est évident que les résultats seront indéterminés s'il y a des documents en double avec exactement le même Creati. à la date.

+0

Si je comprends bien votre requête, il suppose qu'un CreationDate plus récent implique un InstanceId plus élevé, donc MAX (CreationDate) correspond toujours à MAX (InstanceID). Je crois que cela ne pourrait pas toujours être vrai (dépendant du générateur InstanceId). – AlexDrenea

+0

@AlexDrenea: Il sélectionne l'InstanceId basé sur "order by CREATIONDATE desc". Cela fonctionnera, même s'il y a deux documents avec le même date de création. Puis retournera celui avec le plus haut InstanceId. – Andomar

+0

@Andomar: Je n'ai pas dit que ça ne marcherait pas pour 2 documents avec le même CreationDate. J'ai dit que l'hypothèse selon laquelle CreationDate plus récent implique un InstanceID plus élevé pourrait être fausse. La question indique clairement "S'assurer que l'InstanceId sur la ligne est la bonne" donc la requête ne devrait pas être faite en tenant compte de telles suppositions. – AlexDrenea

1

Voici une version pour SQL Server. Fondamentalement, vous rejoignez la table avec la table résultant en regroupant les lignes par la colonne DocumentId et en obtenant max (creationDate). En utilisant ces 2 colonnes comme condition pour obtenir la valeur du code. Fondamentalement, la clé primaire pour la sélection requise est DocumentName et CreationDate. Ceux-ci identifient de manière unique (ou devraient uniquement identifier) ​​la ligne que vous essayez de sélectionner. Pour obtenir cette clé, nous créons une seconde table (temp) avec une clause select et une clause groupBy. Nous rejoignons cette table avec celle d'origine et utilisons les informations pour la sélection.

SELECT 
    mt2.DocumentId 
    ,mt2.CreationDate 
    ,mt1.InstanceId 
FROM 
    myTable mt1 
    inner join (SELECT 
        DocumentId DocumentId 
        ,MAX(CreationDate) CreationDate 
      FROM  
        myTable 
      GROUP BY 
        DocumentId 
       )mt2 on mt2.DocumentId = mt1.DocumentId 
        and mt2.CreationDate = mt1.CreationDate 
ORDER BY mt2.DocumentId 

La valeur creationDate doit être unique par DocumentId pour que la requête s'exécute correctement. Si vous avez besoin de plus d'entrées par jour et par document, vous pouvez envisager de réduire la granularité de CreationDate (par exemple ajouter le composant Time)

0

Cela devrait fonctionner sur la plupart des bases de données:

SELECT 
    cur.DocumentId, cur.CreationDate, cur.InstanceId 
FROM 
    DocumentVersions cur 
LEFT OUTER JOIN 
    DocumentVersions next 
    ON next.DocumentId = cur.DocumentId 
    AND next.CreationDate > cur.CreationDate 
WHERE 
    next.DocumentId is null 

Il se joint à la table de document contre lui-même, la recherche un document avec le même identifiant et un CreationDate supérieur. L'instruction where indique que le document avec la date la plus élevée ne doit pas être trouvé, filtrant efficacement sur le document le plus récent par DocumentId.

S'il pourrait y avoir plusieurs documents avec la même date de création, vous pouvez sélectionner celui qui a le plus haut InstanceId comme:

SELECT 
    cur.DocumentId, cur.CreationDate, max(cur.InstanceId) 
FROM 
    DocumentVersions cur 
LEFT OUTER JOIN 
    DocumentVersions next 
    ON next.DocumentId = cur.DocumentId 
    AND next.CreationDate > cur.CreationDate 
WHERE 
    next.DocumentId is null 
GROUP BY 
    cur.DocumentId, cur.CreationDate 
+0

Est-ce que cela fonctionnera s'il n'y a qu'une seule ligne pour le documentId particulier (c'est-à-dire le document BCA dans mon exemple)? – SCdF

+0

Ouais cela devrait fonctionner, la jointure ne trouvera aucun document plus tard que le document, et il apparaîtra dans le résultat. – Andomar

Questions connexes