sql - 如果为 Null,则 HOLD 先前的非 Null 值
问题描述
我正在使用 SQL Server。我想用前一个(最后一个)非空值替换表中的所有 NULLS,以填补数据中的 NULL 空白。例如,假设我有一个表,其中一些值为 NULL:
DECLARE @Table TABLE(
dt datetime2(0),
v1 INT,
v2 INT,
v3 INT,
v4 INT,
v5 INT,
v999 INT
)
INSERT INTO @Table (dt,v1,v2,v3,v4,v5,v999) SELECT '6/12/2021 03:45', 3, 4, 8, 5, NULL, 2
INSERT INTO @Table (dt,v1,v2,v3,v4,v5,v999) SELECT '6/12/2021 03:46', 9, NULL, 2, NULL, 1, 0
INSERT INTO @Table (dt,v1,v2,v3,v4,v5,v999) SELECT '6/12/2021 03:47', 5, 2, NULL, 7, 8, NULL
INSERT INTO @Table (dt,v1,v2,v3,v4,v5,v999) SELECT '6/12/2021 03:48', 9, 0, NULL, 6, 6, NULL
INSERT INTO @Table (dt,v1,v2,v3,v4,v5,v999) SELECT '6/12/2021 03:49', NULL, 7, 0, 0, 3, NULL
INSERT INTO @Table (dt,v1,v2,v3,v4,v5,v999) SELECT '6/12/2021 03:50', 6, 2, 7, 3, NULL, NULL
桌子:
但是假设我有大约 200 万行和大约 200 列。
我已经为每一列尝试了 SELECT 语句,但速度非常慢。我也尝试过使用 UPDATE 语句(也使用 SELECT),它非常慢。我找不到 SQL Server 的 LAST_VALUE 和 IGNORE NULLS 的良好替代方案。您对如何用大量行和列的最后一个非空值替换 NULLS 有任何想法吗?
编辑:我希望结果看起来像这样,其中先前的非空值将填充每列的任何计算的空值:
我为每一列尝试了更新语句,但查询速度很慢。它们是这样的,但我尝试了几种。使用 Select 的所有尝试都非常慢。
UPDATE #table SET v1 = (SELECT TOP 1 u.v1 FROM #table u WHERE u.v1 is not null AND u.dt <= #table.dt ORDER BY u.dt DESC)
编辑#2:为了清楚问题而进行了编辑,因为我希望在列中的 NULL 间隙中“保留最后一个非值”。
解决方案
没有简单、便宜的方法可以做到这一点。部分问题在于您的数据模型。有这么多列是非常可疑的。而且,更糟糕的是,他们似乎有相似的数据。它们可能应该存储在不同的行中。
你能做什么?好吧,你可以这样做:
with toupdate as (
select t.*,
first_value(v1) over (order by (case when v1 is not null then 1 else 2 end), dt desc) as last_v1,
first_value(v2) over (order by (case when v2 is not null then 1 else 2 end), dt desc) as last_v2,
. . .
from t
)
update toupdate
set v1 = coalesce(v1, last_v1),
v2 = coalesce(v2, last_v2),
. . . ;
我提醒您,更新大表中的所有行需要很长时间。但这是表达查询的一种相对简单的方式。
请注意,SQL Server 确实对查询或结果集中的列数有限制,因此这不适用于任意数量的列。
推荐阅读
- javascript - 遍历嵌套数组,通过id找到特定的叶子节点,并将其移除
- python - 使用进程更新 gui 项目
- php - 用php选择选项内的值
- c# - C#中如何使用for()循环进行赋值操作?
- postgresql - 如何在 Postgresql 中创建一个文件夹来保存输出?
- android - 如何通过邮件 FIREBASE 确定用户是否更改了密码
- android - 如何在 Activity 中使用 findNavController()
- c# - 一段时间后无法登录网站
- java - 如何将 Java 日期时间代码转换为 Python
- spring-boot - 错误:执行 jar 时无法找到或加载主类