sql - 将阶段标识符分配给启停事件表

标签 sql sql-server tsql

我想将计算列添加到启停事件表中,以充当“阶段”标识符。不幸的是,我来自源系统的数据并不总是干净的,我的意思是不会总是有一对开始和停止事件;有时会出现没有相应开始的停止事件,反之,也有没有相应停止的开始事件。

下表是我的测试数据。倒数第二列是我使用窗口函数计算此列的错误尝试。最后一列显示了我正在寻找的正确预期结果。

列是:

  • id:开始停止事件所属的“作业”标识符。
  • ordinal:作业中事件的顺序。
  • category:事件是开始还是结束。 a = 开始,b = 停止。
  • 不正确:我在计算这个阶段 ID 时的错误尝试。
  • 正确:我想要的结果。

id 序号类别不正确正确 1 1 一个 1 1 1 2 乙 1 1 1 3 一个 2 2 1 4 乙 2 2 2 1 一个 1 1 2 2 乙 1 1 2 3 一个 2 2 2 4 乙 2 2 2 5 一个 3 3 3 1 乙 1 1 3 2 一个 1 2 3 3 乙 2 2 3 4 一个 2 3 3 5 b 3 3

可以看出,我的尝试对 id 1 和 2 有效,但对 3 无效,因为它没有按要求将事件分组。

到目前为止我的查询是:

select *,
       Incorrect = row_number() over (partition by id, category order by ordinal)
from #Test
order by id, ordinal

希望这已经足够清楚了。感谢您的帮助。

最佳答案

你可以试试这个:

SELECT *
       ,SUM(IIF([category] = 'a', 1, 0)) OVER (PARTITION BY [id] ORDER BY [ordinal] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) 
FROM @DataSource
ORDER BY [id], [ordinal];

enter image description here

完整代码如下:

DECLARE @DataSource TABLE
(
     [id] TINYINT
    ,[ordinal] TINYINT
    ,[category] CHAR(1)
);

INSERT INTO @DataSource ([id], [ordinal], [category])
VALUES   ('1', '1', 'a')
        ,('1', '2', 'b')
        ,('1', '3', 'a')
        ,('1', '4', 'b')
        ,('2', '1', 'a')
        ,('2', '2', 'b')
        ,('2', '3', 'a')
        ,('2', '4', 'b')
        ,('2', '5', 'a')
        ,('3', '1', 'b')
        ,('3', '2', 'a')
        ,('3', '3', 'b')
        ,('3', '4', 'a')
        ,('3', '5', 'b');


SELECT *
       ,SUM(IIF([category] = 'a', 1, 0)) OVER (PARTITION BY [id] ORDER BY [ordinal] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) 
FROM @DataSource
ORDER BY [id], [ordinal];

请注意,在某些情况下,当 id 组的第一个元素是 b 时,最后的列值从 0 开始。如果这是一个问题,您可以尝试在这种情况下添加 1:

SELECT  DS.*
       ,SUM(IIF([category] = 'a', 1, 0)) OVER (PARTITION BY [id] ORDER BY [ordinal] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + dsf.[fix]
FROM @DataSource DS
INNER JOIN
(
    SELECT [id] as fix_id
          ,IIF(category = 'a', 0, 1) as fix
    FROM @DataSource
    WHERe [ordinal] = 1
) DSF
    ON DS.id = DSF.[fix_id]
ORDER BY [id], [ordinal];

enter image description here

关于sql - 将阶段标识符分配给启停事件表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45999828/

相关文章:

sql - 在 SQL Server 中加密列上的运算符搜索

tsql - 您如何计算两个日期之间的星期数?

mysql - 基于第一个表合并多个表的数据

MySQL - 有条件地添加来自不同表的值?

c# - Ado.net firebird 提交向表中插入新行

sql - 能否根据SQL Server license查询最大数据库大小?

sql-server - 没有 Entity Framework 的 .NET Core 6 SQL Server 连接

sql-server - 为什么使用 "fake table"ObjectProperty 确定某些系统表为 "TableIsFake"?

sql - 按 hstore 中任意属性的值排序

mysql - 选择重复项