0

在我的数据库中,我有一个包含 3 列的表:日期时间、参数、值。我的目标是获取数据的一个子集。我想获取参数 = 'B' 和 value > 5 之后的所有行(在结果集中包括这一行)。忽略参数 = 'B' 和 value <=5 之后的所有行(在结果集中包括此行)。

源表和预期结果

换句话说,我想在参数 = B 的行中使用 VALUE 作为标志(伪代码):


    include_flag = 0
    result_set = empty table
    
    for row in rows:
        if parameter = B and value > 5:
            result_set.append(row)
            include_flag = 1
        elif parameter = B and value <= 5:
            result_set.append(row)
            include_flag = 0
        elif parameter <> B:
            if include_flag = 1:
                result_set.append(row)
            elif include_flag = 0:
                skip(row)

源表:

约会时间 范围 价值
1.9.2021 12:34:00 一个 0.50
2.9.2021 14:01:00 7.40
2.9.2021 21:52:00 C 85.40
3.9.2021 3:15:00 3.80
4.9.2021 1:42:00 C 67.30
5.9.2021 12:34:00 一个 0.3
6.9.2021 12:34:00 C 76.50
6.9.2021 17:22:00 一个 0.40
6.9.2021 19:37:00 8.10
7.9.2021 12:34:00 C 91.70
7.9.2021 22:12:00 C 87.60
8.9.2021 7:17:00 一个 0.60
9.9.2021 5:34:00 5.80
9.9.2021 12:34:00 4.90
10.9.2021 19:56:00 一个 0.60

期望的结果集:

约会时间 范围 价值
2.9.2021 14:01:00 7.40
2.9.2021 21:52:00 C 85.40
3.9.2021 3:15:00 3.80
6.9.2021 19:37:00 8.10
7.9.2021 12:34:00 C 91.70
7.9.2021 22:12:00 C 87.60
8.9.2021 7:17:00 一个 0.60
9.9.2021 5:34:00 5.80
9.9.2021 12:34:00 4.90

此外,我对导致替代结果集的解决方案感兴趣,该结果集与源表具有相同的行数,但仅包含主要结果集中包含的那些值。(因此(参数='B'和值<=5)之后的行也包括在内,只是值被忽略了)

  • 解决方案有何不同?

替代结果集:

约会时间 范围 价值
1.9.2021 12:34:00 一个
2.9.2021 14:01:00 7.40
2.9.2021 21:52:00 C 85.40
3.9.2021 3:15:00 3.80
4.9.2021 1:42:00 C
5.9.2021 12:34:00 一个
6.9.2021 12:34:00 C
6.9.2021 17:22:00 一个
6.9.2021 19:37:00 8.10
7.9.2021 12:34:00 C 91.70
7.9.2021 22:12:00 C 87.60
8.9.2021 7:17:00 一个 0.60
9.9.2021 5:34:00 5.80
9.9.2021 12:34:00 4.90
10.9.2021 19:56:00 一个
  • 这个问题的最佳解决方案是什么?

任何帮助,将不胜感激。

编辑:

询问:

SELECT t.parameter, t.date_time, t.value, B_over_limit = CASE 
   WHEN t.parameter = 'B' AND t.value > 5.0 THEN 1 
   WHEN t.parameter = 'B' AND t.value <= 5.0 THEN 0 
   ELSE null END
FROM table t ORDER BY t.date_time

带来:

约会时间 范围 价值 B_over_limit
1.9.2021 12:34:00 一个 0.50 无效的
2.9.2021 14:01:00 7.40 1
2.9.2021 21:52:00 C 85.40 无效的
3.9.2021 3:15:00 3.80 0
4.9.2021 1:42:00 C 67.30 无效的
5.9.2021 12:34:00 一个 0.3 无效的
6.9.2021 12:34:00 C 76.50 无效的
6.9.2021 17:22:00 一个 0.40 无效的
6.9.2021 19:37:00 8.10 1
7.9.2021 12:34:00 C 91.70 无效的
7.9.2021 22:12:00 C 87.60 无效的
8.9.2021 7:17:00 一个 0.60 无效的
9.9.2021 5:34:00 5.80 1
9.9.2021 12:34:00 4.90 0
10.9.2021 19:56:00 一个 0.60 无效的
  • 用最后一个 0 或 1 填充所有空值几乎是最终结果。我怎样才能做到这一点?
  • 即使用前一个查询作为子查询,然后类似(?):
SELECT s.parameter, s.date_time, s.values, 
LAST_VALUE(s.B_over_limit) OVER(...) FROM subquery s ORDER BY date_time

子查询的结果和所需的中间结果

4

1 回答 1

0

您需要有一个唯一的列 (id) 并使用“<strong>OUTER APPLY”来获得预期的结果。

由于您的示例数据没有唯一列,因此我创建了一个临时表来创建唯一 id 列并存储示例数据。

  1. 样本输入:

在此处输入图像描述

  1. 创建一个临时表,其中包含一个标识列和输入数据中的所有列。
  2. 按 date_time 将输入数据按顺序插入到临时表中,以维护数据顺序。

温度表:

在此处输入图像描述

  1. 从此临时表编写查询以生成 B_over_limit 列并将其插入另一个临时表以供进一步使用。

在此处输入图像描述

  1. 现在编写一个带有外部应用的查询,以在 NULL 时获取列的先前值以获取最终结果。

在此处输入图像描述

询问:

select * from tb1 --sample source data
order by date_time

--create temp table #t1 (use original table datatypes)
   create table #t1
   (id int identity not null,
    date_time varchar(50), 
    parameter char(1),
    value float
   )

 insert into #t1  insert input into 
 select * from tb1 order by convert(datetime,date_time)

 select * from #t1;

 SELECT id, t.date_time, t.parameter, t.value, 
   B_over_limit = CASE WHEN t.parameter = 'B' AND t.value > 5.0 THEN 1 
                       WHEN t.parameter = 'B' AND t.value <= 5.0 THEN 0 
                       ELSE null 
                   END 
 into #t2
 FROM #t1 t ORDER BY convert(datetime,t.date_time)

 select * from #t2

 select a.date_time, a.parameter, a.value,
     case when id = 1 and a.B_over_limit is NULL then 0 
     else ISNULL(a.B_over_limit, t.B_over_limit) 
     end as B_over_limit
 from #t2 a
 outer apply
   (select top 1 B_over_limit from #t2 b 
       where b.id < a.id and b.date_time is not null 
         and b.parameter is not null and b.value is not null
         and b.B_over_limit is not null
         and a.B_over_limit is null 
       order by id desc ) t
于 2021-10-08T13:22:52.000 回答