我有一张桌子(MySQL)
UserID | CreationTS | Type | Value | Bonus Value
259275 | 2012-08-01 | Deposit | -------- | NULL
259275 | 2012-08-02 | BonusApplied | 175 | 175
259275 | 2012-08-03 | TradeOrder | -------- | 175
259275 | 2012-08-06 | TradeOrder | -------- | 175
259275 | 2012-08-10 | BonusApplied | 180 | 180
259275 | 2012-08-11 | TradeOrder | -------- | 180
259275 | 2012-08-12 | TradeOrder | -------- | 180
259275 | 2012-08-15 | TradeOrder | -------- | 180
259275 | 2012-08-17 | BonusApplied | 200 | 200
259275 | 2012-08-18 | TradeOrder | -------- | 200
259681 | 2012-08-01 | Deposit | -------- | NULL
259681 | 2012-08-02 | BonusApplied | 175 | 175
259681 | 2012-08-03 | TradeOrder | -------- | 175
259681 | 2012-08-06 | TradeOrder | -------- | 175
259681 | 2012-08-10 | BonusApplied | 180 | 180
259681 | 2012-08-11 | TradeOrder | -------- | 180
259681 | 2012-08-12 | TradeOrder | -------- | 180
259681 | 2012-08-15 | TradeOrder | -------- | 180
259681 | 2012-08-17 | BonusApplied | 200 | 200
259681 | 2012-08-18 | TradeOrder | -------- | 200
我需要根据每个用户的第一个值和BonusApplied填写在每个UserID的BonusApplied类型之间填充的VALUE中的空白。 最终值位于“奖励值”列中。这就是我需要的。 如果有一个基于@variables的解决方案而不是JOIN,那就太好了。
答案 0 :(得分:1)
试试这个:
CREATE TABLE bonusTable (userID INT UNSIGNED, CreationTs DATE, `Type` CHAR(32), `Value` INT UNSIGNED, BonusValue INT);
INSERT INTO bonusTable VALUES
(259275, '2012-08-01', 'Deposit', NULL, NULL),
(259275, '2012-08-02', 'BonusApplied', 175, 175),
(259275, '2012-08-03', 'TradeOrder', NULL, 175),
(259275, '2012-08-06', 'TradeOrder', NULL, 175),
(259275, '2012-08-10', 'BonusApplied', 180, 180),
(259275, '2012-08-11', 'TradeOrder', NULL, 180),
(259275, '2012-08-12', 'TradeOrder', NULL, 180),
(259275, '2012-08-15', 'TradeOrder', NULL, 180),
(259275, '2012-08-17', 'BonusApplied', 200, 200),
(259275, '2012-08-18', 'TradeOrder', NULL, 200),
(259681, '2012-08-01', 'Deposit', NULL, NULL),
(259681, '2012-08-02', 'BonusApplied', 175, 175),
(259681, '2012-08-03', 'TradeOrder', NULL, 175),
(259681, '2012-08-06', 'TradeOrder', NULL, 175),
(259681, '2012-08-10', 'BonusApplied', 180, 180),
(259681, '2012-08-11', 'TradeOrder', NULL, 180),
(259681, '2012-08-12', 'TradeOrder', NULL, 180),
(259681, '2012-08-15', 'TradeOrder', NULL, 180),
(259681, '2012-08-17', 'BonusApplied', 200, 200),
(259681, '2012-08-18', 'TradeOrder', NULL, 200);
SET @VUserID := NULL;
SET @VValue := NULL;
SELECT CreationTs, `Type`, IF(@VUserID = userID, IF(`Value` IS NULL, @VValue, @VValue := `Value`), @VValue := `Value`) BonusValue, @VUserID := userID userID FROM bonusTable ORDER BY userID, CreationTs;
#Cols in original order:
SELECT userID, CreationTs, `Type`, BonusValue FROM (
SELECT CreationTs, `Type`, IF(@VUserID = userID, IF(`Value` IS NULL, @VValue, @VValue := `Value`), @VValue := `Value`) BonusValue, @VUserID := userID userID FROM bonusTable ORDER BY userID, CreationTs
) A;
答案 1 :(得分:0)
这是一个JOIN类型解决方案:
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id INT NOT NULL
,seq INT NOT NULL
,value INT NULL
,PRIMARY KEY(id,seq)
);
INSERT INTO my_table VALUES
(101, 1,NULL),
(101, 2,175),
(101, 4,NULL),
(101, 7,NULL),
(101, 9,180),
(101,11,NULL),
(102, 2,NULL),
(102, 3,175),
(102, 4,NULL),
(102, 7,NULL),
(102, 9,200),
(102,12,NULL);
SELECT x.*
, MAX(y.value) i
FROM my_table x
JOIN my_table y
ON y.id = x.id
AND y.seq <= x.seq
GROUP
BY x.id,x.seq;
+-----+-----+-------+------+
| id | seq | value | i |
+-----+-----+-------+------+
| 101 | 1 | NULL | NULL |
| 101 | 2 | 175 | 175 |
| 101 | 4 | NULL | 175 |
| 101 | 7 | NULL | 175 |
| 101 | 9 | 180 | 180 |
| 101 | 11 | NULL | 180 |
| 102 | 2 | NULL | NULL |
| 102 | 3 | 175 | 175 |
| 102 | 4 | NULL | 175 |
| 102 | 7 | NULL | 175 |
| 102 | 9 | 200 | 200 |
| 102 | 12 | NULL | 200 |
+-----+-----+-------+------+
答案 2 :(得分:0)
这与Strawberry的答案类似,但适用于奖金值的上升和下降:
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id INT NOT NULL
,seq INT NOT NULL
,value INT NULL
,PRIMARY KEY(id,seq)
);
INSERT INTO my_table VALUES
(101, 1,NULL),
(101, 2,175),
(101, 4,NULL),
(101, 7,NULL),
(101, 9,180),
(101,11,NULL),
(102, 2,NULL),
(102, 3,175),
(102, 4,NULL),
(102, 7,NULL),
(102, 9,150),
(102,12,NULL);
SELECT
x.*,
(SELECT value FROM my_table
WHERE id = x.id
AND seq = MAX(y.seq)) filled
FROM my_table x
LEFT JOIN my_table y
ON y.id = x.id
AND y.seq <= x.seq
AND y.value IS NOT NULL
GROUP BY
x.id, x.seq
结果:
+-----+-----+-------+------+
| id | seq | value | i |
+-----+-----+-------+------+
| 101 | 1 | NULL | NULL |
| 101 | 2 | 175 | 175 |
| 101 | 4 | NULL | 175 |
| 101 | 7 | NULL | 175 |
| 101 | 9 | 180 | 180 |
| 101 | 11 | NULL | 180 |
| 102 | 2 | NULL | NULL |
| 102 | 3 | 175 | 175 |
| 102 | 4 | NULL | 175 |
| 102 | 7 | NULL | 175 |
| 102 | 9 | 150 | 150 |
| 102 | 12 | NULL | 150 |
+-----+-----+-------+------+
工作原理:
y.seq <= x.seq
和y.value IS NOT NULL
表达式将具有相同ID的所有非空前行添加到每个原始行GROUP BY x.id, x.seq
子句允许我们通过MAX(y.seq)
选择最高的前序号