2

使用 SQL Server 2008+ 不知道如何提问,所以这里有一些示例数据:

case_id start_time          timer_name  type    value   duration
8386    2013-02-01 19:25:52 Patient In  25      1       NULL
8386    2013-02-01 20:18:31 Patient Out 25      0       NULL
8386    2013-02-01 20:13:13 Anes. Start 26      1       NULL
8386    2013-02-01 20:18:37 Anes. Stop  26      0       NULL
8386    2013-02-01 20:13:25 Induction   27      1       NULL
8386    2013-02-01 20:18:41 Emergence   27      0       NULL
8386    2013-02-01 20:13:31 Incision    28      1       NULL
8386    2013-02-01 20:18:45 Closing     28      0       NULL
8451    2013-02-06 18:37:44 Anesthesia  1       1       NULL
8451    2013-02-06 18:37:48 Incision    1       1       NULL
8451    2013-02-06 18:05:32 Patient In  25      1       NULL
8451    2013-02-06 18:07:41 Anes. Start 26      1       NULL
8451    2013-02-06 18:11:00 Induction   27      1       NULL
8451    2013-02-06 18:11:54 Emergence   27      0       NULL
8451    2013-02-06 18:11:20 Incision    28      1       NULL

这是我用来生成此列表的 SQL:

SELECT        case_id, start_time, timer_name, type, value, duration
FROM          dbo.event AS ev WITH (nolock)
WHERE         (type IN (1, 2, 3, 25, 26, 27, 28)) AND (defunct = 'N')
ORDER BY      case_id, type, start_time

我需要做的是将类型分组在一起,按 case_id、type 和 start_time 排序,然后计算第一个值为 1 的条目与下一个值为 0 的相同类型的条目之间的持续时间。上述数据中,案例8386应该有以下数据:

8386    2013-02-01 19:25:52 Patient In  25      1       52:39
8386    2013-02-01 20:13:13 Anes. Start 26      1       5:24
8386    2013-02-01 20:13:25 Induction   27      1       5:16
8386    2013-02-01 20:13:31 Incision    28      1       5:14

希望我做对了。持续时间不需要采用该格式。我希望秒数最好,但这种格式在问题中更容易阅读。在 timer_name 字段中显示什么名称也无关紧要。

了解我可能会在一行中为一个类型获得多个 1 值或在一行中获得多个 0 值。我需要将第一个 1 与第一个 0 联系起来并计算持续时间,然后寻找下一个 1,等等。这意味着每种类型可能有多个分组,每种情况。如果没有为 1 值找到 0 值,那么我将使用可以从另一个表中提取的 case_end_time。

4

2 回答 2

1

此版本的查询使用相关子查询根据您的逻辑查找下一个开始时间。在 SQL Server 2012 中,这将使用该lead()函数,但该函数不可用:

select case_id, start_time, timer_name, type, value, duration,
       (select top 1 start_time
        from event e2
        where e2.case_id = e.case_id and e2.type = e.type and e2.value = 0 and
              e2.start_time > e.start_time
        order by start_time desc
       ) - start_time as duration
from event e
WHERE (type IN (1, 2, 3, 25, 26, 27, 28)) AND (defunct = 'N') and value = 1

您的示例没有多个“0”。如果您只想要第一个,我们可以使用以下方法找到它row_number()

select case_id, start_time, timer_name, type, value, duration,
       (next_start_time - start_time) as duration
from (select case_id, start_time, timer_name, type, value, duration,
             (select top 1 start_time
              from event e2
              where e2.case_id = e.case_id and e2.type = e.type and e2.value = 0 and
                    e2.start_time > e.start_time
              order by start_time desc
             ) as next_start_time,
             ROW_NUMBER() over (partition by case_id, type order by start_time) as seqnum
      from event e
      WHERE (type IN (1, 2, 3, 25, 26, 27, 28)) AND (defunct = 'N') and value = 1
     ) t
where seqnum = 1
于 2013-04-25T18:07:52.523 回答
0

好的,你必须使用一堆东西,首先,要获取第一个 1 和 0,你需要使用按值分区的 ROW_NUMBER 函数,这样你就不能使用 where 子句按 row = 1 过滤。此时您将拥有每种情况下的 1 和 0 中的第一个。如果您对单独的查询执行此操作,您可以加入它们并在两个日期之间产生差异。像这样的一些事情:

    SELECT 
      case_id, type, DATEDIFF(mm, a.start_time, b.start_time) duration 
    FROM 
       (SELECT        case_id, start_time, timer_name, type, value, duration
        FROM          dbo.event AS ev WITH (nolock)
        WHERE       (type IN (1, 2, 3, 25, 26, 27, 28)) AND (defunct = 'N') 
            AND ROW_NUMBER() OVER(PARTITION BY type, value ORDER BY case_id, type) = 1 --Get the first row only
            AND TYPE = 0 -- And the ones of type 0
       ) a INNER JOIN   
       (SELECT        case_id, start_time, timer_name, type, value, duration
        FROM          dbo.event AS ev WITH (nolock)
        WHERE       (type IN (1, 2, 3, 25, 26, 27, 28)) AND (defunct = 'N') 
            AND ROW_NUMBER() OVER(PARTITION BY type, value ORDER BY case_id, type) = 1 --Get the first row only
            AND TYPE = 1 -- And the ones of type 1          
       ) b
   ON
    a.case_id = b.case_id AND
    a.[type] = b.[type]

我还没有测试它,但这就是想法

于 2013-04-25T18:21:32.727 回答