需要帮助向前和向后填写 SQL 查询
Need help in forward and backward filling in SQL query
我需要使用日期列确定每个团队在 x 列和 y 列中花费的时间。为此,我正在处理 x 列的后向填充和 y 列的前向填充,以便我可以计算每个团队的开始时间和结束时间之间的差异。
X 列必须向后填充直到同一数字中的前一个值,注意:它不应该应用于另一个数字。
Y 列必须向前填充直到同一数字内的下一个值,注意:它不应应用于另一个数字。
在前向填充和后向填充方面需要帮助 table。
这是数据现在的样子。
数据如何处理 运行 查询 - X 列向后和 Y 列向前
Number
Date
Sl_NO
Column_X
Column_Y
Column_X_Backward
Column_Y_Forward
1
44563
1
NULL
NULL
A
NULL
1
44563
2
A
B
A
B
1
44563
3
NULL
NULL
C
B
1
44563
4
NULL
NULL
C
B
1
44563
5
NULL
NULL
C
B
1
44563
6
NULL
NULL
C
B
1
44563
7
C
D
C
D
1
44563
8
NULL
NULL
E
D
1
44563
9
E
F
E
F
1
44563
10
NULL
NULL
NULL
F
1
44563
11
NULL
NULL
NULL
F
1
44563
12
NULL
NULL
NULL
F
2
44563
1
NULL
NULL
A
NULL
2
44563
2
A
B
A
B
2
44563
3
NULL
NULL
C
B
2
44563
4
NULL
NULL
C
B
2
44563
5
C
D
C
D
2
44563
6
NULL
NULL
E
D
2
44563
7
E
B
E
B
2
44563
8
NULL
NULL
B
B
2
44563
9
NULL
NULL
B
B
2
44563
10
B
A
B
A
2
44563
11
NULL
NULL
NULL
A
2
44563
12
NULL
NULL
NULL
A
这里的 X 列必须回填到前一个值,它应该在相同的数字内,Y 列必须向前填充到相同数字内的下一个值。
希望有人能够帮助我解决同样的问题。
您可以使用标量子查询来完成。不幸的是,只有 Sql 服务器的 Azur 版本支持 first_value()
函数中的 IGNORE NULLS
选项。
select t1.*
, coalesce(Column_X,
(select top(1) t2.Column_X
from mytable t2
where t2.Number = t1.Number and t2.Column_X is not null and t2.Sl_NO > t1.Sl_NO order by Sl_NO)) x2
, coalesce(Column_Y,
(select top(1) t2.Column_Y
from mytable t2
where t2.Number = t1.Number and t2.Column_X is not null and t2.Sl_NO < t1.Sl_NO order by Sl_NO desc)) y2
from mytable t1
这是 lptr 作为评论发布的。我将其作为社区维基答案发布以保存它,以防评论再次被删除。
他们在这里使用派生的 table 来执行窗口聚合,执行“累积”计数。然后他们使用派生的 table 获得 MAX
值,这些值再次被窗口化。
create table t(Number int, Date int, Sl_NO int, Column_X char(1), Column_Y char(1))
insert into t(Number, Date, Sl_No, Column_X, Column_Y)
values
(1, 44563, 1, NULL, NULL),
(1, 44563, 2, 'A', 'B'),
(1, 44563, 3, NULL, NULL),
(1, 44563, 4, NULL, NULL),
(1, 44563, 5, NULL, NULL),
(1, 44563, 6, NULL, NULL),
(1, 44563, 7, 'C', 'D'),
(1, 44563, 8, NULL, NULL),
(1, 44563, 9, 'E', 'F'),
(1, 44563, 10, NULL, NULL),
(1, 44563, 11, NULL, NULL),
(1, 44563, 12, NULL, NULL),
(2, 44563, 1, NULL, NULL),
(2, 44563, 2, 'A', 'B'),
(2, 44563, 3, NULL, NULL),
(2, 44563, 4, NULL, NULL),
(2, 44563, 5, 'C', 'D'),
(2, 44563, 6, NULL, NULL),
(2, 44563, 7, 'E', 'B'),
(2, 44563, 8, NULL, NULL);
select Number, Date, Sl_No,
Column_X,
max(Column_X) over(partition by Number, Date, cntColumn_X) as Column_X_Backward,
Column_Y,
max(Column_Y) over(partition by Number, Date, cntColumn_Y) as Column_Y_Forward
from
(
select *,
count(Column_X) over(partition by Number, Date order by Sl_NO rows between unbounded preceding and 1 preceding) as cntColumn_X,
count(Column_Y) over(partition by Number, Date order by Sl_NO) as cntColumn_Y
from t
) as t
我需要使用日期列确定每个团队在 x 列和 y 列中花费的时间。为此,我正在处理 x 列的后向填充和 y 列的前向填充,以便我可以计算每个团队的开始时间和结束时间之间的差异。
X 列必须向后填充直到同一数字中的前一个值,注意:它不应该应用于另一个数字。
Y 列必须向前填充直到同一数字内的下一个值,注意:它不应应用于另一个数字。
在前向填充和后向填充方面需要帮助 table。
这是数据现在的样子。
数据如何处理 运行 查询 - X 列向后和 Y 列向前
Number | Date | Sl_NO | Column_X | Column_Y | Column_X_Backward | Column_Y_Forward |
---|---|---|---|---|---|---|
1 | 44563 | 1 | NULL | NULL | A | NULL |
1 | 44563 | 2 | A | B | A | B |
1 | 44563 | 3 | NULL | NULL | C | B |
1 | 44563 | 4 | NULL | NULL | C | B |
1 | 44563 | 5 | NULL | NULL | C | B |
1 | 44563 | 6 | NULL | NULL | C | B |
1 | 44563 | 7 | C | D | C | D |
1 | 44563 | 8 | NULL | NULL | E | D |
1 | 44563 | 9 | E | F | E | F |
1 | 44563 | 10 | NULL | NULL | NULL | F |
1 | 44563 | 11 | NULL | NULL | NULL | F |
1 | 44563 | 12 | NULL | NULL | NULL | F |
2 | 44563 | 1 | NULL | NULL | A | NULL |
2 | 44563 | 2 | A | B | A | B |
2 | 44563 | 3 | NULL | NULL | C | B |
2 | 44563 | 4 | NULL | NULL | C | B |
2 | 44563 | 5 | C | D | C | D |
2 | 44563 | 6 | NULL | NULL | E | D |
2 | 44563 | 7 | E | B | E | B |
2 | 44563 | 8 | NULL | NULL | B | B |
2 | 44563 | 9 | NULL | NULL | B | B |
2 | 44563 | 10 | B | A | B | A |
2 | 44563 | 11 | NULL | NULL | NULL | A |
2 | 44563 | 12 | NULL | NULL | NULL | A |
这里的 X 列必须回填到前一个值,它应该在相同的数字内,Y 列必须向前填充到相同数字内的下一个值。
希望有人能够帮助我解决同样的问题。
您可以使用标量子查询来完成。不幸的是,只有 Sql 服务器的 Azur 版本支持 first_value()
函数中的 IGNORE NULLS
选项。
select t1.*
, coalesce(Column_X,
(select top(1) t2.Column_X
from mytable t2
where t2.Number = t1.Number and t2.Column_X is not null and t2.Sl_NO > t1.Sl_NO order by Sl_NO)) x2
, coalesce(Column_Y,
(select top(1) t2.Column_Y
from mytable t2
where t2.Number = t1.Number and t2.Column_X is not null and t2.Sl_NO < t1.Sl_NO order by Sl_NO desc)) y2
from mytable t1
这是 lptr 作为评论发布的。我将其作为社区维基答案发布以保存它,以防评论再次被删除。
他们在这里使用派生的 table 来执行窗口聚合,执行“累积”计数。然后他们使用派生的 table 获得 MAX
值,这些值再次被窗口化。
create table t(Number int, Date int, Sl_NO int, Column_X char(1), Column_Y char(1)) insert into t(Number, Date, Sl_No, Column_X, Column_Y) values (1, 44563, 1, NULL, NULL), (1, 44563, 2, 'A', 'B'), (1, 44563, 3, NULL, NULL), (1, 44563, 4, NULL, NULL), (1, 44563, 5, NULL, NULL), (1, 44563, 6, NULL, NULL), (1, 44563, 7, 'C', 'D'), (1, 44563, 8, NULL, NULL), (1, 44563, 9, 'E', 'F'), (1, 44563, 10, NULL, NULL), (1, 44563, 11, NULL, NULL), (1, 44563, 12, NULL, NULL), (2, 44563, 1, NULL, NULL), (2, 44563, 2, 'A', 'B'), (2, 44563, 3, NULL, NULL), (2, 44563, 4, NULL, NULL), (2, 44563, 5, 'C', 'D'), (2, 44563, 6, NULL, NULL), (2, 44563, 7, 'E', 'B'), (2, 44563, 8, NULL, NULL); select Number, Date, Sl_No, Column_X, max(Column_X) over(partition by Number, Date, cntColumn_X) as Column_X_Backward, Column_Y, max(Column_Y) over(partition by Number, Date, cntColumn_Y) as Column_Y_Forward from ( select *, count(Column_X) over(partition by Number, Date order by Sl_NO rows between unbounded preceding and 1 preceding) as cntColumn_X, count(Column_Y) over(partition by Number, Date order by Sl_NO) as cntColumn_Y from t ) as t