这个问题是来自Link的后续问题。我在不同的时间点 t 有一个人 (id) 和一个特征 (var0) 的表。在某些时间点缺少特征,我想用前一个值填补空白。下面是一个表格示例:
+---+---+----+ +----+---+------+------+------------------+
|id | t |var0| | id | t | var0 | var1 | @prev_id := id |
+---+---+----+ +----+---+------+------+------------------+
| 1 | 1 | a | | 1 | 1 | a | a | 1 |
| 1 | 3 | \N | | 1 | 3 | \N | a | 1 |
| 1 | 7 | \N | | 1 | 7 | \N | a | 1 |
| 1 | 8 | b | | 1 | 8 | b | b | 1 |
| 1 | 9 | \N | | 1 | 9 | \N | b | 1 |
| 2 | 2 | \N | | 2 | 2 | \N | \N | 2 |
| 2 | 4 | u | | 2 | 4 | u | u | 2 |
| 2 | 5 | u | | 2 | 5 | u | u | 2 |
| 2 | 6 | \N | | 2 | 6 | \N | u | 2 |
| 2 | 7 | \N | | 2 | 7 | u | u | 2 |
| 2 | 8 | v | | 2 | 8 | v | v | 2 |
| 2 | 9 | \N | | 2 | 9 | \N | v | 2 |
+---+---+----+ +----+---+------+------+------------------+
左表是原始 x1 表,右表是请求表。这是获取结果的代码:
DROP TABLE IF EXISTS test01.x1;
CREATE TABLE test01.x1 (
id INTEGER
, t INTEGER
, var0 CHAR(1)
) ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8 COLLATE = utf8_unicode_ci
;
INSERT INTO test01.x1(id,t,var0) VALUES
( 1,1,'a' )
,(1,3,NULL)
,(1,7,NULL)
,(1,8,'b' )
,(1,9,NULL)
,(2,2,NULL)
,(2,4,'u' )
,(2,5,'u' )
,(2,6,NULL)
,(2,7,'u')
,(2,8,'v' )
,(2,9,NULL)
;
DROP TABLE IF EXISTS test01.x2;
CREATE TABLE test01.x2
SELECT id, t
, var0
, @prev_var0 := CAST(IF(id = @prev_id AND var0 IS NULL AND @prev_var0 IS NOT NULL
, @prev_var0
, var0
) AS CHAR
) var1
, @prev_id := id
FROM test01.x1, (SELECT @prev_id := NULL
,@prev_var0 := NULL
) init
ORDER BY id, t
;
ALTER TABLE test01.x2 MODIFY var1 CHAR(1) DEFAULT NULL;
DROP TABLE IF EXISTS test01.x2;
CREATE TABLE test01.x2
SELECT * FROM test01.x1;
UPDATE test01.x1, (SELECT @prev_id := NULL
, @prev_var0 := NULL
) init
SET var0 = @prev_vr0 := IF(id = @prev_id AND var0 IS NULL AND @prev_var0 IS NOT NULL
, @prev_var0
, var0
)
, @prev_id := id
ORDER BY id, t
我会对另一种解决方案感兴趣。而不是创建一个新表 x2,我想更新表 x1 的 var0。我试过这个:
UPDATE test01.x1, (SELECT @prev_id := NULL
, @prev_var0 := NULL
) init
SET var0 = @prev_vr0 := IF(id = @prev_id AND var0 IS NULL AND @prev_var0 IS NOT NULL
, @prev_var0
, var0
)
, @prev_id := id
ORDER BY id, t
但是它不起作用有两个原因(也许还有其他原因):
- 多表 UPDATE 不允许使用 ORDER BY(请参阅链接)
- @prev_id := id 不起作用。显然,在 SET 语句中,不可能将值直接分配给用户定义的变量。
有谁知道我怎样才能得到没有间隙的左表?
感谢帮助。