You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何利用System Versioned Tables获取用户各职位分段的起止时间

Correct SQL Query to Get Position History with System Versioned Tables (Handling Reverted Positions)

Got it, I see exactly where your original approach fell short—grouping directly by UserId, CompanyId, and Position merges all identical roles for a user together, even when they’re separated by a different position in between. That’s why User 1’s reverted Assistant role wasn’t showing up as a distinct segment. Let’s fix this with a window function-based solution that tracks consecutive position periods.

Sample Data

UserIdCompanyIdPositionOtherSysStartTimeSysEndTime
11AssistantA2019-12-01 13:00:002019-12-01 14:00:00
21ManagerA2019-12-01 13:00:002019-12-01 20:00:00
11AssistantB2019-12-01 14:00:002019-12-01 17:00:00
11ManagerA2019-12-01 17:00:002019-12-01 20:00:00
21ExecutiveA2019-12-01 20:00:009999-12-31 23:59:59
31CEOA2019-12-01 13:00:009999-12-31 23:59:59
11AssistantA2019-12-01 20:00:009999-12-31 23:59:59

Correct SQL Query

WITH RankedPositions AS (
    SELECT 
        UserId,
        CompanyId,
        Position,
        SysStartTime,
        SysEndTime,
        -- Create a unique group ID for each consecutive position segment
        SUM(CASE WHEN prev_position = Position THEN 0 ELSE 1 END) 
            OVER (PARTITION BY UserId, CompanyId ORDER BY SysStartTime) AS position_group
    FROM (
        SELECT 
            UserId,
            CompanyId,
            Position,
            SysStartTime,
            SysEndTime,
            -- Fetch the previous position for the same user/company to detect changes
            LAG(Position) OVER (PARTITION BY UserId, CompanyId ORDER BY SysStartTime) AS prev_position
        FROM dbo.CompanyUser FOR SYSTEM_TIME ALL
    ) AS position_history
)
SELECT 
    UserId,
    CompanyId,
    Position,
    MIN(SysStartTime) AS SysStartTime,
    MAX(SysEndTime) AS SysEndTime
FROM RankedPositions
GROUP BY UserId, CompanyId, Position, position_group
ORDER BY UserId, CompanyId, SysStartTime;

How This Works

  1. Inner Subquery (position_history): Uses the LAG() window function to pull the position from the immediately preceding version for each user/company, ordered by SysStartTime. This lets us check if the current position is the same as the last one.
  2. CTE (RankedPositions): Creates a position_group value. Every time the position changes from the previous row, we increment the group ID. This groups together all consecutive rows where the user held the same position (even if other fields like Other were modified).
  3. Final SELECT: Groups by UserId, CompanyId, Position, and position_group—this ensures we only merge identical positions that are consecutive, not all identical positions across the user’s history. We then take the minimum start time and maximum end time for each group to get the full duration of that position segment.

Expected Output

UserIdCompanyIdPositionSysStartTimeSysEndTime
11Assistant2019-12-01 13:00:002019-12-01 17:00:00
11Manager2019-12-01 17:00:002019-12-01 20:00:00
11Assistant2019-12-01 20:00:009999-12-31 23:59:59
21Manager2019-12-01 13:00:002019-12-01 20:00:00
21Executive2019-12-01 20:00:009999-12-31 23:59:59
31CEO2019-12-01 13:00:009999-12-31 23:59:59

内容的提问来源于stack exchange,提问作者Ben

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:10:15