SQL Server 根据指标从另一列设置日期列值(窗口功能)

iaqfqrcu  于 2023-01-08  发布在  其他
关注(0)|答案(2)|浏览(88)

编辑:我正在使用SQL Server(托管示例)
在我的表中,我尝试:设置PrevMktOpenDate = CalendarDate,其中MarketOpen是最后一个1。我希望这在我下面的示例摘录中得到更好的说明。
表格:
市场日历
色谱柱:
天数(整数)
日历日期(日期)
市场开放(位)
上一个市场开放日期(日期)
当前:

364 2022-12-30  1   2022-12-29
365 2022-12-31  0   2022-12-30
1   2023-01-01  0   2022-12-31
2   2023-01-02  0   2023-01-01
3   2023-01-03  1   2022-12-02
4   2023-01-04  1   2023-01-03

请求:

364 2022-12-30  1   2022-12-29
365 2022-12-31  0   2022-12-30
1   2023-01-01  0   2022-12-30
2   2023-01-02  0   2023-01-30
3   2023-01-03  1   2022-12-30
4   2023-01-04  1   2023-01-03

我试过写一个按日期排序的排名函数,但无法让它按预期工作。

hfyxw5xn

hfyxw5xn1#

大概是这样的(给了3个alt):

if object_id('tempdb..#t_open') is not null
drop table #t_open
create table #t_open(
    Day int
,   CalendarDate date
,   MarketOpen bit
,   PrevMktOpenDate date
)

insert into #t_open (
    Day, CalendarDate, MarketOpen, PrevMktOpenDate
)
select  *
from
(
    VALUES  (363,'2022-12-29',1,'2022-12-28')
    ,   (364,'2022-12-30',1,'2022-12-29')
    ,   (365,'2022-12-31',0,'2022-12-30')
    ,   (1  ,'2023-01-01',0,'2022-12-31')
    ,   (2  ,'2023-01-02',0,'2023-01-01')
    ,   (3  ,'2023-01-03',1,'2022-12-02')
    ,   (4  ,'2023-01-04',1,'2023-01-03')
) t (day, cd, mo, pm)

-- Alternative one
update  t
set PrevMktOpenDate = prev
from (
    SELECT  *
    ,   MAX(CASE WHEN MarketOpen = 1 THEN CalendarDate END) OVER(ORDER BY CalendarDate ROWS BETWEEN unbounded preceding and 1 preceding) AS prev
    FROM    #t_open o
) t

-- Alternative two
update  t
set PrevMktOpenDate = prev
from #t_open t
CROSS APPLY (
    SELECT  TOP 1 o.Calendardate AS prev
    FROM    #t_open o
    WHERE o.CalendarDate < t.CalendarDate
    AND o.MarketOpen = 1
    oRDER BY o.CalendarDate DESC
) prev

-- ALternative three
update  t
set PrevMktOpenDate = (SELECT TOP 1 o.Calendardate AS prev
    FROM    #t_open o
    WHERE o.CalendarDate < t.CalendarDate
    AND o.MarketOpen = 1
    oRDER BY o.CalendarDate DESC)
from #t_open t

select  *
from    #t_open
2w3rbyxf

2w3rbyxf2#

假设您使用的是Azure SQL数据库,则可以使用窗口函数LAST_VALUE,其中包含CASE表达式和IGNORE NULLS

SELECT Col1,
       Col2,
       Col3,
       ISNULL(LAST_VALUE(CASE Col3 WHEN 1 THEN Col2 END) IGNORE NULLS OVER (ORDER BY Col2 ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING),Col4) AS Col4
FROM (VALUES(364,CONVERT(date,'2022-12-30'),1,CONVERT(date,'2022-12-29')),
            (365,CONVERT(date,'2022-12-31'),0,CONVERT(date,'2022-12-30')),
            (1  ,CONVERT(date,'2023-01-01'),0,CONVERT(date,'2022-12-31')),
            (2  ,CONVERT(date,'2023-01-02'),0,CONVERT(date,'2023-01-01')),
            (3  ,CONVERT(date,'2023-01-03'),1,CONVERT(date,'2022-12-02')),
            (4  ,CONVERT(date,'2023-01-04'),1,CONVERT(date,'2023-01-03')))V(Col1,Col2,Col3,Col4);

db<>fiddle

相关问题