2013-07-15 3 views
0

J'essaie de trouver un moyen d'obtenir seulement 16 lignes (ce qui est 16 enregistrements distincts basés sur SERV_ACCT) avec seulement le compte récent. J'utilise Distinct et grouper par et je pensais que cela résoudrait le problème, mais je continue à obtenir 20 lignes.Colonnes SQL Server distinctes

DECLARE

@CustomerID int = 8, 
@UtilityCompanyID int = 1 


    SELECT DISTINCT SERV_ACCT, ACCOUNT, MAX(INV_DATE) 
    FROM tblAPSData 

    WHERE SERV_ACCT NOT IN (SELECT ServiceAccount 
       FROM tblMEP_Meters 
       JOIN tblMEP_Sites 
       ON tblMEP_Meters.SiteID = tblMEP_Sites.ID 

       JOIN tblMEP_Projects 
       ON tblMEP_Projects.ID = tblMEP_Sites.ProjectID 

       WHERE CustomerID = 8 
       AND Type = 1 
       ) 

    AND ACCOUNT IN (SELECT AccountNumber 
        FROM tblMEP_CustomerAccounts 
        WHERE CustomerID = @CustomerID 
        AND UtilityCompanyID = @UtilityCompanyID) 

    AND INV_DATE > DATEADD(month, -6, getdate()) 
    GROUP BY SERV_ACCT, ACCOUNT 
    ORDER BY SERV_ACCT 

le résultat est le suivant:

SERV_ACCT ACCOUNT (No column name) 
0289S61288 117512280 2013-06-12 00:00:00.000 
0492S90281 117512280 2013-06-12 00:00:00.000 
0492S90281 651412281 2013-04-08 00:00:00.000 
1303S90280 117512280 2013-06-12 00:00:00.000 
1435S01282 117512280 2013-06-12 00:00:00.000 
1440S13289 312937281 2013-06-24 00:00:00.000 
1548S00286 117512280 2013-06-12 00:00:00.000 
1548S00286 308710287 2013-04-08 00:00:00.000 
2498S21288 117512280 2013-06-12 00:00:00.000 
5384S92284 979437282 2013-06-24 00:00:00.000 
5538S21284 117512280 2013-06-12 00:00:00.000 
6109S12286 117512280 2013-06-12 00:00:00.000 
7358S00281 117512280 2013-06-12 00:00:00.000 
7358S00281 659710281 2013-04-08 00:00:00.000 
7488S22289 117512280 2013-06-12 00:00:00.000 
8058S12287 117512280 2013-06-12 00:00:00.000 
9058S00288 117512280 2013-06-12 00:00:00.000 
9168S00282 117512280 2013-06-12 00:00:00.000 
9168S00282 570810282 2013-04-08 00:00:00.000 
9645S21281 117512280 2013-06-12 00:00:00.000 
+1

Puisque vous regroupez par '' SERV_ACCT' et ACCOUNT' vous retournerez toutes les combinaisons de 'DISTINCT' de ces deux champs, vous devez décider quelles valeurs vous voulez revenir, vous pouvez utiliser MAX/MIN si c'est par date. –

Répondre

0

D'abord, je combiner où les déclarations de clause dans JOIN pour une meilleure performance. Utilisez ensuite une fonction de partitionnement pour classer vos lignes par date.

RANK (Transact-SQL)

SELECT * FROM 
(
SELECT 
aps.SERV_ACCT 
, aps.ACCOUNT 
, ROW_NUMBER() OVER (PARTITION BY aps.SERV_ACCT ORDER BY aps.INV_DATE DESC) [row] 
    FROM tblAPSData aps 
    INNER JOIN tblMEP_Meters mep 
     ON aps.SERV_ACCT = mep.ServiceAccount 
    INNER JOIN tblMEP_Sites site 
     ON site.SiteID = mep.ID 
    INNER JOIN tbl_MEP_Projects proj 
     ON proj.ID = site.ProjectID 
     AND proj.CustomerID = 8 -- Move this to appropriate table 
     AND proj.Type = 1 --Move this to appropriate table assumed it was on proj 
    INNER JOIN tblMEP_CustomerAccounts custAcc 
     ON custAcc.AccountNumber = aps.Account 
     AND custAcc.CustomerID = @CustomerID 
     AND custAcc.UtilityCompanyID = @UtilityCompanyID 
WHERE aps.INV_DATE > DATEADD(month, -6, getdate()) 
) data 
WHERE 
    data.row = 1 
2

Si vous utilisez au moins SQL Server 2005, vous pouvez utiliser les fonctions de classement comme ROW_NUMBER dans un cte:

WITH CTE AS(
    SELECT [SERV_ACCT], [ACCOUNT], [INV_DATE], 
    RN = ROW_NUMBER() OVER (PARTITION BY SERV_ACCT ORDER BY INV_DATE DESC) 
    FROM dbo.Table1 
) 
SELECT [SERV_ACCT], [ACCOUNT], [INV_DATE] 
FROM CTE 
WHERE RN = 1 

DEMO

+0

Pour mon code, où ajoutez-vous ce bout de code? Je ne suis pas sûr. Je vous remercie. –

+0

Vous pouvez ajouter votre requête complète au cte qui est similaire à une sous-requête. La partie importante est le row_number avec la partition par laquelle retourne One pour le dernier enregistrement de chaque Serv_Acct. –

Questions connexes