0
votes

Obtenir la première occurrence par date dans SQL Server

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?


5 commentaires

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 / 2019 pour Flag1 et 09 / Mar / 2019 pour Flag2


La 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.


3 Réponses :


0
votes

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.


0 commentaires

0
votes

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


3 commentaires

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 .. :)



0
votes

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


0 commentaires