Je veux classer la valeur "Lapsed" de l'indicateur de statut de telle manière qu'il se réinitialise après avoir rencontré une autre valeur et quand il rencontre à nouveau "Lapsed", il devrait recommencer le classement à partir de 1
je suis confus que comment pouvons-nous faire une telle chose dans SQL. J'ai essayé avec des fonctions analytiques mais pas de chance
Les données ressemblent à ceci.
id yr_mon status lapsed_months ---------------------------------------- 1002 201703 New 0 1002 201704 Retained 0 1002 201705 Unretained 0 1002 201706 Lapsed 1 1002 201707 Lapsed 2 1002 201708 Reactivated 0 1002 201709 lapsed 1 1002 201710 Unretained 0 1002 201711 Lapsed 1 1002 201712 Lapsed 2 1003 201703 New 0 1003 201704 Retained 0 1003 201705 Lapsed 1 1003 201706 Lapsed 2 1003 201707 Reactivated 0 1003 201708 Lapsed 1 1003 201709 Lapsed 2 1003 201710 Lapsed 3
La sortie devrait ressembler à ceci.
id yr_mon status ------------------------- 1002 201703 New 1002 201704 Retained 1002 201705 Unretained 1002 201706 Lapsed 1002 201707 Lapsed 1002 201708 Reactivated 1002 201709 lapsed 1002 201710 Unretained 1002 201711 Lapsed 1002 201712 Lapsed 1003 201703 New 1003 201704 Retained 1003 201705 Lapsed 1003 201706 Lapsed 1003 201707 Reactivated 1003 201708 Lapsed 1003 201709 Lapsed 1003 201710 Lapsed
3 Réponses :
Essayez de générer le RowNumber comme ci-dessous. Veuillez utiliser la commande appropriée des données selon les exigences.
id yr_mon Status lapsed_months 1002 201703 New 0 1002 201704 Retained 0 1002 201705 Unretained 0 1002 201706 Lapsed 1 1002 201707 Lapsed 2 1002 201708 Reactivated 0 1002 201709 Retained 0 1002 201710 Unretained 0 1002 201711 Lapsed 1 1002 201712 Lapsed 2 1003 201801 New 0 1003 201802 Retained 0 1003 201803 Lapsed 1 1003 201804 Lapsed 2 1003 201710 Lapsed 3
La sortie peut être (mais, en l'absence de clause ORDER BY, non garantie):
SELECT * , @row_num :=IF(`status` = 'Lapsed',@row_num+1,0)AS RowNumber
FROM
(
SELECT 1002 id,201703 yr_mon, 'New' `status` UNION ALL
SELECT 1002,201704,'Retained' UNION ALL
SELECT 1002,201705,'Unretained' UNION ALL
SELECT 1002,201706,'Lapsed' UNION ALL
SELECT 1002,201707,'Lapsed' UNION ALL
SELECT 1002,201708,'Reactivated' UNION ALL
SELECT 1002,201709,'Retained' UNION ALL
SELECT 1002,201710,'Unretained' UNION ALL
SELECT 1002,201711,'Lapsed' UNION ALL
SELECT 1002,201712,'Lapsed' UNION ALL
SELECT 1003,201801,'New' UNION ALL
SELECT 1003,201802,'Retained' UNION ALL
SELECT 1003,201803,'Lapsed' UNION ALL
SELECT 1003,201804,'Lapsed' UNION ALL
SELECT 1003,201710,'Lapsed'
)A
Merci, pouvez-vous expliquer la syntaxe que vous avez utilisée
Une variable en ligne @row_num est utilisée et la valeur attribuée à cette variable compte tenu de la valeur de la colonne Status . Si la valeur est 'Lapsed', j'augmente simplement la valeur @row_num en définissant @row_num = @ row_num + 1 et pour toutes les autres valeurs, définissez @row_num = 0.
Puis-je demander, s'il vous plaît, quelle base de données cette requête est en cours d'exécution?
MySQL, comme vous l'avez marqué,
Depuis la version 8.0, MySql prend en charge les fonctions de fenêtre. Groupez et numérotez les lignes dans un groupe
with grp as ( select id, yr_mon, status , row_number() over(partition by id order by yr_mon) - row_number() over(partition by id, status order by yr_mon) grp from tlog ) select id, yr_mon, status, case status when 'Lapsed' then row_number() over(partition by id, grp order by yr_mon) else 0 end lapsed_months from grp order by id, yr_mon;
fiddle https: //dbfiddle.uk/?rdbms=mysql_8.0&fiddle=2d4fcfa5458096c0f3bf296099660d1c Notez que je place intentionnellement les données source dans un ordre arbitraire.
Vraisemblablement, vous voulez cela pour chaque id .
Vous voulez juste une somme cumulative des valeurs "caduques" . Vous pouvez exprimer cela dans MySQL 8+ comme suit:
select * ,
(@rn := if(@id = id,
if(status = 'lapsed', @rn + 1, @rn),
0
)
) as lapsed_months
from (select t.*
from t
order by t.id, t.yr_mon
) t cross join
(select @i := -1, @rn := 1) params;
Dans les versions antérieures, vous pouvez utiliser des variables comme celle-ci:
select l.*,
sum(status = 'lapsed') over (partition by id order by yr_mon) as lapsed_months
from t;
p>