2013-06-21 2 views
1

J'ai une vue en SQL qui rassemble certaines données dans lesquelles j'ai besoin d'éliminer les valeurs en double. J'ai essayé d'utiliser DISTINCT et GROUP BY sans succès. Fondamentalement, ce que nous avons en cours est une série de fichiers téléchargés qui sont attachés à un fournisseur en fonction du type de document qu'il est. Ils téléchargeront plusieurs versions du document au cours des différentes phases des signatures.éléments en double dans la vue SQL/requête

Chaque fois qu'ils téléchargent une nouvelle phase du document, une nouvelle ligne est ajoutée à la table UploadedDocuments, le RequiredDocumentsID reste le même mais le nom de fichier dans la table UploadedFiles (ainsi que le champ ID dans cette table) sont nouveaux.

Historiquement, cela n'a pas été un problème car nous recherchons normalement cette information un fournisseur à la fois - auquel cas nous prenons simplement la plus récente pour chaque type de document. Maintenant, cependant, nous avons une nouvelle page qui est en cours d'élaboration et qui doit afficher TOUS les fournisseurs à la fois, mais il suffit de lister chacun une seule fois et de ne lister que les colonnes Filename/Path les plus récentes.

Voici la vue que j'ai actuellement. Comme mentionné précédemment, j'ai essayé de mettre la première valeur comme 'DISTINCT dbo.ReqDocuments.ID' ainsi que de faire un GroupBy. Les deux thèses ont échoué à éliminer l'un des doublons. Je pensais à un OUI appliqué, mais mes compétences tSQL ne sont pas encore à ce niveau.

SELECT dbo.UploadedFiles.FileName, dbo.UploadedFiles.FilePath,  
dbo.ReqDocuments.ProviderID, dbo.Providers.CompanyName, 
dbo.ReqDocuments.ID AS RequiredDocumentID, dbo.UploadedFiles.aDate,  
dbo.UploadedFiles.aUser 
FROM dbo.Providers 
INNER JOIN dbo.ReqDocuments ON dbo.Providers.ID = dbo.ReqDocuments.ProviderID 
INNER JOIN dbo.UploadedFiles ON dbo.ReqDocuments.ID = dbo.UploadedFiles.ReqDocumentsID 
WHERE (dbo.ReqDocuments.DocumentID = 50) 

Répondre

1

Plus simplement, étant donné un DocumentID, vous voulez une liste de (ProviderID, FilePath) où le FilePath est le plus récent pour cette DocumentID et ProviderID combinaison.

Je classerais tous vos chemins de fichiers partitionnement par ProviderID et commande par Date:

SELECT outerF.FileName, outerF.FilePath,  
    outerD.ProviderID, outerP.CompanyName, 
    outerD.ID AS RequiredDocumentID, outerF.aDate,  
    outerF.aUser 
FROM dbo.Providers outerP 
INNER JOIN dbo.ReqDocuments outerD ON outerP.ID = outerD.ProviderID 
INNER JOIN dbo.UploadedFiles outerF ON outerD.ID = outerF.ReqDocumentsID 
WHERE (outerD.DocumentID = 50) 
AND outerF.aDate = (
    SELECT top 1 innerF.aDate 
    FROM dbo.ReqDocuments innerD 
    INNER JOIN dbo.UploadedFiles innerF ON innerD.ID = innerF.ReqDocumentsID 
    WHERE innerD.ProviderID = outerP.id 
    AND innerD.DocumentID = outerD.DocumentID 
    ORDER BY innerF.aDate DESC) 
+0

Mes excuses pour ne pas mentionner, mais cette base de données est actuellement encore sur SQL 2000. Il devrait être déplacé à 2008 dans le "proche" futur, nous avons travaillé à travers les problèmes avec une application héritée et le futur proche semble continuellement s'allonger. – Talion83

+0

@ Talion83 J'ai modifié la réponse pour utiliser des sous-requêtes corrélées au lieu du rang. Je n'ai pas votre schéma complet, donc il peut y avoir une meilleure colonne à sélectionner dans la requête interne, comme innerF.ID. –

+0

Génial qui semble le faire! Merci beaucoup pour l'aide. – Talion83

1

Vous pouvez utiliser un ROW_NUMBER() pour résoudre ce:

SELECT * 
FROM (SELECT UploadedFiles.FileName, UploadedFiles.FilePath,  
ReqDocuments.ProviderID, Providers.CompanyName, 
dbo.ReqDocuments.ID AS RequiredDocumentID, dbo.UploadedFiles.aDate,  
dbo.UploadedFiles.aUser 
    , ROW_NUMBER() OVER (PARTITION BY ReqDocuments.ProviderID, Providers.CompanyName, ReqDocuments.ID ORDER BY UploadedFiles.aDate DESC) as RowRank 
FROM dbo.Providers 
INNER JOIN dbo.ReqDocuments ON dbo.Providers.ID = dbo.ReqDocuments.ProviderID 
INNER JOIN dbo.UploadedFiles ON dbo.ReqDocuments.ID = dbo.UploadedFiles.ReqDocumentsID 
WHERE (dbo.ReqDocuments.DocumentID = 50) 
)sub 
WHERE RowRank = 1 

PARTITION BY les champs qui ne changeront pas avec chaque téléchargement et la date ORDER BY décroissant pour afficher la plus récente. Vous pouvez exécuter la requête interne pour avoir une idée du fonctionnement du ROW_NUMBER().

Aussi, j'aime alias, donc voici ceci:

SELECT * 
FROM (SELECT upl.FILENAME 
      , upl.FILEPATH 
      , Req.ProviderID 
      , prv.CompanyName 
      , Req.ID AS RequiredDocumentID 
      , upl.aDate 
      , upl.aUser 
      , ROW_NUMBER() OVER (PARTITION BY Req.ProviderID, prv.CompanyName, Req.ID ORDER BY upl.aDate DESC) as RowRank 
    FROM Providers prv 
    INNER JOIN ReqDocuments Req 
      ON prv.ID = Req.ProviderID 
    INNER JOIN UploadedFiles upl 
      ON Req.ID = upl.ReqDocumentsID 
    WHERE (Req.DocumentID = 50) 
    )sub 
WHERE RowRank = 1 
+0

Mes excuses pour ne pas mentionner, mais ce DB est actuellement encore SQL 2000. Il devrait être déplacé à 2008 dans le "proche" avenir, nous avons travaillé à travers des problèmes avec une application héritée et le proche avenir semble toujours s'allonger. – Talion83

0

Cette requête trouver les doublons

SELECT t1.ID FROM Table t1,Table t2 where t1.Name=t2.Name and t1.ID>t2.ID 
Questions connexes