SQL Server中右表有多个相同值的条目时如何连接表?

问题描述 投票:0回答:1

我想测量店内订单履行每个阶段的提前期,这些提前期应该在现有视图中可用。

视图有几个列和条目,但为了简化考虑这两列和这个特定的条目:

ORDER_NR 身份证
SE2844697 3824

在表格 [OnlineFulFillmentActionLogs] 上,我根据订单履行的每个阶段有不同的状态:

行动日期 OnlineFulFillmentId 状态
2023-04-18 12:27:31.0000000 3824 0
2023-04-18 12:43:20.0000000 3824 1
2023-04-18 12:43:46.0000000 3824 3
2023-04-18 12:46:26.0000000 3824 3
2023-04-18 12:46:26.0000000 3824 5

有些情况下同一状态有多个条目。我可以用 min(Action_Date) 来解决这个问题,以获得第一次出现的日期。我还可以使用此查询计算每个阶段的提前期:

ISNULL(DATEDIFF(HOUR,Column1,Column2),0) AS [LEAD_TIME_FIRST_STAGE] where,
  • Column1 将是 status=0 的 Action_Date;
  • Column2 将是状态 = 1 的 Action_Date,如果存在的话;

但是我正在努力弄清楚如何将这个右表 [OnlineFulFillmentActionLogs] 加入现有视图,因为我有多个条目具有相同的值 OnlineFulFillmentId=3824 并且我想计算每个状态的提前期(从状态 0到状态 1,从状态 1 到状态 2,从状态 2 到状态 3,...)

预期结果:

ORDER_NR 身份证 LEAD_TIME_FIRST_STAGE LEAD_TIME_SECOND_STAGE LEAD_TIME_THIRD_STAGE ...
SE2844697 3824 16 ... ... ...
sql sql-server join case window-functions
1个回答
0
投票

首先,指定下一个和当前状态。如果下一个记录等于指定的下一个状态,则计算

如果时间 Status 列是动态的,你应该使用 sql 动态计算窗口函数的时间,然后使用 pivot

--ORDER_NR  Id  LEAD_TIME_FIRST_STAGE   LEAD_TIME_SECOND_STAGE  LEAD_TIME_THIRD_STAGE
;with _listsatus as(
         select 0 as currentstatus,1 nextstatus union 
         select 1 as currentstatus,2 nextstatus union 
         select 2 as currentstatus,3 nextstatus union 
         select 3 as currentstatus,4 nextstatus union 
         select 4 as currentstatus,5 nextstatus union 
         select 5 as currentstatus,6 nextstatus
 )
SELECT 
        ORDER_NR
        ,id
        ,ISNULL(cast( [0] as varchar(100)),'-') LEAD_TIME_FIRST_STAGE
        ,ISNULL(cast([1] as varchar(100)),'-') LEAD_TIME_SECOND_STAGE
        ,ISNULL(cast( [2] as varchar(100)),'-') LEAD_TIME_three_STAGE
        ,ISNULL(cast( [3] as varchar(100)),'-') LEAD_TIME_Four_STAGE
        ,ISNULL(cast( [4] as varchar(100)),'-') LEAD_TIME_Five_STAGE
        ,ISNULL(cast( [5] as varchar(100)),'-') LEAD_TIME_Sex_STAGE
        
FROM   
(
     
             select ORDER_NR,id,Status, case 
                        when   exists(  select * 
                                       from _listsatus  
                                       where currentstatus=Status   and nextstatus= nStatus 
                                     ) then
                    ISNULL(DATEDIFF(MINUTE, ACTION_DATE,nACTION_DATE ),0) else null end AS [DATEDIFF_STAGE]         
             from (
             select ORDER_NR,id,Status,
             ACTION_DATE,
        
                   LEAD(Status) over(partition by a.OnlineFulFillmentId order by Status) as nStatus
                    , LEAD(ACTION_DATE) over(partition by a.OnlineFulFillmentId order by ACTION_DATE) as nACTION_DATE
                    from OnlineFulFillmentActionLogs a
                    inner join OnlineFulFillment b on a.OnlineFulFillmentId=b.Id
            )a
) t 
PIVOT(
    sum([DATEDIFF_STAGE]) 
    FOR Status IN (
        [0], 
        [1], 
        [2],
        [3],
        [4],
        [5])
) AS pivot_table;


基础数据:

create table OnlineFulFillment
(ORDER_NR varchar(100), Id int)
insert into OnlineFulFillment values('SE2844697','3824')

create table OnlineFulFillmentActionLogs(
ACTION_DATE datetime,   OnlineFulFillmentId int,    Status int)
insert into OnlineFulFillmentActionLogs values('2023-04-18 12:27:31',   3824,   0)
insert into OnlineFulFillmentActionLogs values('2023-04-18 12:43:20',   3824,   1)
insert into OnlineFulFillmentActionLogs values('2023-04-18 12:43:46',   3824,   3)
insert into OnlineFulFillmentActionLogs values('2023-04-18 12:46:26',   3824,   3)
insert into OnlineFulFillmentActionLogs values('2023-04-18 12:46:26',   3824,   5)

© www.soinside.com 2019 - 2024. All rights reserved.