J'ai une table dans SQL Server comme ci-dessous:
SELECT
Flag1, Flag2, Eff_From
FROM
(SELECT
Flag1, Flag2, Eff_From,
ROW_NUMBER() OVER (PARTITION BY Flag1, Flag2 ORDER BY Eff_From) rn
FROM
@ProposalTemp) t
WHERE
rn = 1
Exemple: à partir de la table Flag1 est "1" à partir du 05 / mars / 2019 sur les wards. Flag2 est "1" à partir du 09 / mars / 2019 sur les wards.
Je voudrais obtenir les dates lorsque changé en active (1) et je ne suis pas passé à '0' pour les deux colonnes (flag1, flag2 )
La sortie souhaitée est
Flag1_Efff_Date Flag2_Efff_Date '2019-03-05' '2019-03-05'
Voici un autre exemple
INSERT INTO @ProposalTemp VALUES (0, 0, '2019-03-01'), (1, 0, '2019-03-01') , (0, 0, '2019-03-03') , (1, 1, '2019-03-05') , (1, 1, '2019-03-07') , (1, 1, '2019-03-09');
Et la sortie souhaitée serait
Flag1_Efff_Date Flag2_Efff_Date '2019-03-05' '2019-03-09'
J'ai essayé un peu .. Je ne sais toujours pas comment écrire cette logique.
DECLARE @ProposalTemp AS TABLE (Flag1 BIT, Flag2 BIT, Eff_From DATE) INSERT INTO @ProposalTemp VALUES (0, 0, '2019-03-01'), (1, 0, '2019-03-01') , (0, 0, '2019-03-03') , (1, 1, '2019-03-05') , (1, 0, '2019-03-07') , (1, 1, '2019-03-09');
Des idées?
3 Réponses :
Vous pouvez essayer ceci.
GO
;with cte as (
select row_number() over (order by eff_from) as Slno, * from @ProposalTemp )
, ctflg1 as (
select * from cte where slno = (select max(slno)+1 from cte where Flag1=0))
, ctflg2 as (
select * from cte where slno = (select max(slno)+1 from cte where Flag2=0))
select Flag1, Flag2, Eff_From from ctflg1
union
select Flag1, Flag2, Eff_From from ctflg2
GO
Découvrez d'abord la valeur individuelle pour flag1 et flag2 en utilisant cte , puis utilisez-la selon vos besoins.
Juste une supposition sauvage car vous n'avez pas fourni la logique requise.
D'après la description et le résultat attendu, il semble que vous vouliez la deuxième instance, l'indicateur est 1
; with cte as
(
SELECT Flag1,Flag2,Eff_From,
Row_number() OVER(ORDER BY Eff_From ) rn
FROM @ProposalTemp
),
f1 as
(
select min(Eff_From) as Flag1Date
from cte f1
where f1.Flag1 = 1
and not exists (select * from cte x where x.Flag1 <> 1 and x.rn > f1.rn)
),
f2 as
(
select min(Eff_From) as Flag2Date
from cte f2
where f2.Flag2 = 1
and not exists (select * from cte x where x.Flag2 <> 1 and x.rn > f2.rn)
)
select *
from f1 cross join f2
Salut..Merci pour la réponse. Je voudrais obtenir les dates lorsque changé en active (1) et ne pas changer à «0» pour les deux colonnes (flag1, flag2). . Voici un autre exemple
et la sortie souhaitée serait Flag1Date Flag2Date 2019-03-05 2019-03-05
veuillez mettre à jour votre question d'origine avec ces informations
Solution mise à jour de travail et merci beaucoup .. :)
Ci-dessous utilise LAG , LEAD pour obtenir les résultats souhaités.
DECLARE @ProposalTemp AS TABLE (Flag1 BIT, Flag2 BIT, Eff_From DATE) INSERT INTO @ProposalTemp VALUES (0, 0, '2019-03-01'), (1, 0, '2019-03-01') , (0, 0, '2019-03-03') , (1, 1, '2019-03-05') , (1, 0, '2019-03-07') , (1, 1, '2019-03-09'); ; WITH CTE_flag1flow as ( select lag(flag1,1,null) over(order by Eff_From desc) as nex, flag1 as curr, lead(flag1,1,null) over(order by Eff_From desc) as prev, Eff_From FROM @ProposalTemp), CTE_flag2flow as ( select lag(flag2,1,null) over(order by Eff_From desc) as nex, flag2 as curr, lead(flag2,1,null) over(order by Eff_From desc) as prev, Eff_From FROM @ProposalTemp) select * from (SELECT max(Eff_from) AS Eff_Flag1 FROM CTE_flag1Flow WHERE curr = 1 AND prev = 0 ) AS c1 CROSS JOIN (SELECT max(Eff_from) AS Eff_Flag2 FROM CTE_flag2Flow WHERE curr = 1 AND prev = 0 ) AS C2
Que voulez-vous dire
Je voudrais obtenir le résultat "05 / Mar / 2019" pour Flag1 et "09 / Mar / 2019" pour Flag2.?Pouvez-vous nous montrer votre résultat attendu?
Veuillez expliquer la logique pour obtenir
05 / Mar / 2019pourFlag1et09 / Mar / 2019pourFlag2La sortie souhaitée est la colonne (Flag1_Efff_Date) -> 2019-03-05 ', column (Flag2_Efff_Date) ->' 2019-03-09 '
@ D-Shih: veuillez vérifier la description maintenant.