2017-04-20 97 views
0

我有一个表(MySQL的)填充在表中的值之间的间隙 - 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类型之间,每用户ID的基础上,第一每个用户的价值和BonusApplied。 最终值位于Bonus Value列中。这就是我需要的。 如果有一个基于@variables而不是JOIN的解决方案,那就太好了。

+0

见http://meta.stackoverflow.com/questions/333952/why-should-i-provide-an -mcve-for-what-looks-to-the-very-simple-sql-query – Strawberry

回答

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; 
+0

工程就像一个魅力!谢谢 – Michael

+0

很高兴得到了帮助。请考虑接受答案(绿色勾号),如果它是最有用的答案并回答了您的问题,或者提示它是否有用。通过这种方式,我对社区的价值得以体现,当我陷入困境并提出问题时,有用答案的可能性就会增加。 –

0

这里的联接类型的解决方案:

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 | 
+-----+-----+-------+------+ 
+0

这是为什么这样工作? – Martin

+0

@Martin这是一个很大的问题。一个有用的技巧是考虑如果我们删除聚合函数并用ORDER BY子句替换了GROUP BY子句,将返回哪些行。 – Strawberry

+0

我真的只是询问某种形式的解释,为什么你发布的SQL的作品,谢谢':-)' – Martin