t-sql - 如何填充前一行中的缺失值

标签 t-sql missing-data

考虑这个表(测试):

C1  C2  Data
----------------
1   101 A1
1   104 A4
1   105 A5
2   101 B1
2   102 B2
2   103 B3
2   105 B5

和这个表(OtherTable)

C2
---
100
101
102
103
104
105
106

我想要的是从最后一个可用行和其他表中填充上面缺失的行 - IE。 C1 获得相同的值,C2 来自 OtherTable,Data 获得相同的值。

C1  C2  Data
----------------
1   101 A1
1   102 A1   -- <<< Filled in from OtherTable & last available row 'A1'
1   103 A1   -- <<< Filled in from OtherTable & last available row 'A1'
1   104 A4
1   105 A5
2   101 B1
2   102 B2
2   103 B3
2   104 B3  -- <<< Filled in from OtherTable &  last available row 'B3'
2   105 B5

我已经构建了这个:

WITH Keys AS 
(
    SELECT 
        T.C1, 
        O.C2
    FROM
        TEST T
        CROSS APPLY (SELECT C2 FROM OtherTable) O 
    GROUP BY
        T.C1, 
        O.C2
),
MaxMin AS
(
    SELECT
        C1,
        MIN(C2) LowerBound,
        MAX(C2) UpperBound
    FROM
        Test 
    GROUP BY
        C1
)
SELECT
    K.C1, 
    K.C2,
    T.Data
FROM
    Keys K
    LEFT JOIN Test T 
        ON      
            T.C1 = K.C1 
            AND T.C2 = K.C2 
    INNER JOIN MaxMin M 
        ON
            K.C1 = M.C1 
            AND K.C2 BETWEEN M.LowerBound AND M.UpperBound

我已经走到这一步了

C1  C2  Data
----------------
1   101 A1
1   102 NULL
1   103 NULL
1   104 A4
1   105 A5
2   101 B1
2   102 B2
2   103 B3
2   104 NULL
2   105 B5

但是我不知道如何应用数据列,而且我也觉得递归 CTE 是为了减少上述查询,但我不知道如何实现。


(这里是获取示例的 TSQL)

IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Test') 
    DROP TABLE Test;

CREATE TABLE Test (C1 INT, C2 INT, Data NVARCHAR(10));

INSERT INTO Test (C1, C2, Data) VALUES
(1, 101, 'A1'),
--(1, 102, 'A1'),
--(1, 103, 'A1'),
(1, 104, 'A4'),
(1, 105, 'A5'),
(2, 101, 'B1'),
(2, 102, 'B2'),
(2, 103, 'B3'),
--(2, 104, 'B3'),
(2, 105, 'B5');


IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'OtherTable') 
    DROP TABLE OtherTable;

CREATE TABLE OtherTable (C2 INT);

INSERT INTO OtherTable (C2) VALUES
(100),
(101),
(102),
(103),
(104),
(105),
(106);

最佳答案

从 CTE 中的测试中查找每个 C1 的最小和最大 C2(不一定是 CTE),并将其加入到 OtherTable使用之间<​​。 使用按 C2 desc 排序的 top(1) 获取与 Data 值相关的子查询

with C as
(
  select C1, 
         min(C2) minC2,
         max(C2) maxC2
  from test
  group by C1
)
select C.C1,
       O.C2,
       (
       select top(1) T.Data
       from test as T
       where T.C1 = C.C1 and
             T.C2 <= O.C2
       order by T.C2 desc
       ) as Data
from C
  inner join OtherTable as O
    on O.C2 between C.minC2 and C.maxC2

SQL Fiddle

关于t-sql - 如何填充前一行中的缺失值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23380782/

相关文章:

sql - 为什么 Clng 在这些场景中的工作方式不同,并且可以在 SQL Server 中重现吗? (不是银行家四舍五入)

sql-server - 使用 DATEADD 添加秒数会返回四舍五入为分钟的值 - 为什么?

python - 类型错误 : NAN/INF not supported in write_number() without 'nan_inf_to_errors' Workbook() option

asp.net-mvc-3 - 无效的对象名称 dbo.TableName

sql - 夏令时和 UTC 时间

T-SQL 查询批量处理数据而不破坏组

missing-data - 在 DolphinDB 中,如何将具有开始日期和结束日期的 1 条记录转换为每天的多条记录?

r - 如何从 Amelia 包中提取完整的数据集

python - 具有潜在缺失值的多重不等式 (a < b < c...)

r - 填补缺失的水平