2 votes

Identifier deux lignes avec 1 an ou plus de différence

J'ai une table appelée finance dans laquelle je stocke tous les paiements du client. Les principales colonnes sont : ID, COSTUMERID, DATEPAID, AMOUNTPAID.

Ce dont j'ai besoin est une liste de dates par COSTUMERID avec les dates de son premier paiement et tout autre paiement supérieur à 1 an du dernier. Exemple :

+----+------------+------------+------------+
| ID | COSTUMERID |  DATEPAID  | AMOUNTPAID |
+----+------------+------------+------------+
|  1 |          1 | 2015-01-10 |         10 |
|  2 |          1 | 2016-01-05 |         30 |
|  2 |          1 | 2017-02-20 |         30 |
|  3 |          2 | 2016-03-15 |        100 |
|  4 |          2 | 2017-02-15 |        100 |
|  5 |          3 | 2017-05-01 |         25 |
+----+------------+------------+------------+

Ce que j'attends comme résultat :

+------------+------------+
| COSTUMERID |  DATEPAID  |
+------------+------------+
|          1 | 2015-01-01 |
|          1 | 2017-02-20 |
|          2 | 2016-03-15 |
|          3 | 2017-05-01 |
+------------+------------+

Le client 1 a 2 dates : la première + une autre qui a plus d'1 an après la dernière.

J'espère que je me suis bien fait comprendre.

3voto

Gordon Linoff Points 213350

Je pense que vous voulez juste lag() :

select t.*
from (select t.*,
             lag(datepaid) over (partition by customerid order by datepaid) as prev_datepaid
      from t
     ) t
where prev_datepaid is null or
      datepaid > dateadd(year, 1, prev_datepaid);

0voto

user7593937 Points 195

La solution de Gordon est correcte, tant que vous ne regardez que la différence de la ligne précédente (paiement précédent), mais je me demande si Antonio cherche des paiements supérieurs à un an après le dernier paiement d'un an, auquel cas cela devient un problème plus complexe à résoudre. Prenons l'exemple suivant :

CREATE TABLE #Test (
     CustomerID smallint 
    ,DatePaid date
    ,AmountPaid smallint )

INSERT INTO #Test
SELECT 1, '2015-1-10', 10
INSERT INTO #Test
SELECT 1, '2016-1-05', 30
INSERT INTO #Test
SELECT 1, '2017-2-20', 30
INSERT INTO #Test
SELECT 1, '2017-6-30', 50
INSERT INTO #Test
SELECT 1, '2018-3-5', 50
INSERT INTO #Test
SELECT 1, '2018-5-15', 50
INSERT INTO #Test
SELECT 2, '2016-3-15', 100
INSERT INTO #Test
SELECT 2, '2017-6-15', 100

WITH CTE AS (
    SELECT 
         CustomerID
        ,DatePaid
        ,LAG(DatePaid) OVER (PARTITION BY CustomerID ORDER BY DatePaid) AS PreviousPaidDate
        ,AmountPaid
    FROM #Test )

SELECT 
     *
    ,-DATEDIFF(DAY, DatePaid, PreviousPaidDate) AS DayDiff
    ,CASE WHEN DATEDIFF(DAY, PreviousPaidDate, DatePaid)  >= 365 THEN 1 ELSE 0 END AS Paid 
FROM CTE 

La ligne numéro 5 est > 1 an après le dernier paiement d'un an, mais soustraire de la ligne précédente ne résout pas ce problème. Cela peut ou non avoir de l'importance, mais je voulais le souligner au cas où c'est ce qu'il veut dire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X