2015-10-07 1 views
3

J'ai table Transactions comme suit dans SQL SERVER.Comment faire pour supprimer les enregistrements en double dans la requête select sur la clause

UserID  TranDate  Amount 
    1 | 2015-04-01 | 0 
    1 | 2015-05-02 | 5000 
    1 | 2015-09-07 | 1000 
    1 | 2015-10-01 | -4000 
    1 | 2015-10-02 | -700 
    1 | 2015-10-03 | 252 
    1 | 2015-10-03 | 260 
    1 | 2015-10-04 | 1545 
    1 | 2015-10-05 | 1445 
    1 | 2015-10-06 | -2000 

Je veux interroger ce tableau pour obtenir le solde disponible à une date particulière. J'ai donc utilisé la fonction de fenêtrage pour cela.

SELECT TransactionDate, 
    SUM(Amount) OVER (PARTITION BY UserId ORDER BY TransactionDate ROWS 
BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM Transactions 

Mais comme table de transactions est d'avoir l'entrée en double pour la date 03/10/2015, il répète des données pour ce jour 03/10/2015. Chaque fois qu'il y a la même date, j'attends le dernier enregistrement de cette date avec le solde disponible résumé.

Sortie courant

TransactionDate  AvailableBalance 
    2015-04-01  |  0 
    2015-05-02  |  5000 
    2015-09-07  |  6000 
    2015-10-01  |  2000 
    2015-10-02  |  1300 
    2015-10-03  |  1552 
    2015-10-03  |  1804 
    2015-10-04  |  3349 
    2015-10-05  |  4794 
    2015-10-06  |  2794 

attendu: Je veux supprimer ci-dessous enregistrement du jeu de résultats ci-dessus.

2015-10-03  |  1552 

HERE est mon violon sql

Répondre

4

Vous pouvez SUM avant que la fonction fenêtré comme:

SqlFiddleDemo

WITH cte AS 
(
    SELECT TransactionDate, UserId, SUM(Amount) AS Amount 
    FROM Transactions 
    GROUP BY TransactionDate, UserId 
) 
SELECT TransactionDate, 
     SUM(Amount) OVER (PARTITION BY UserId ORDER BY TransactionDate ROWS 
    BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS AvailableBalance 
FROM cte 
1

Utilisation RANGE au lieu de ROWS.

SQL Fiddle

SELECT 
    TransactionDate, 
    SUM(Amount) OVER (
    PARTITION BY UserId 
    ORDER BY TransactionDate 
    RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS AvailableBalance 
FROM Transactions; 

Cette variante donne un résultat différent fixé à l'origine demandé, mais il peut être utile dans certains cas. Cette variante renvoie le même nombre de lignes que dans la table Transactions. Ainsi, il retournera deux lignes avec 2015-10-03, mais pour les deux lignes AvailableBalance serait 1804.

Je voulais juste souligner qu'il y a cette option RANGE. Si vous avez vraiment besoin d'une ligne par jour, alors le regroupement par jour au début comme dans la réponse par @ lad2025 est le chemin à parcourir.

+0

OP devra ajouter «DISTINCT». Deux clés en double sont ramenées '2015-10-03 1804' –

+0

@EvaldasBuinauskas, oui, vous avez raison. Cette variante produit un jeu de résultats différent de celui demandé à l'origine, mais il peut être utile dans certains cas. Je voulais juste souligner qu'il y a cette option 'RANGE'. Si vous avez vraiment besoin d'une ligne par jour, alors le regroupement par jour au début comme dans la réponse par @ lad2025 est le chemin à parcourir. –

+0

Ne pas discuter. C'est en effet un conseil très utile. –