如何处理这个问题

时间:2014-08-14 05:10:41

标签: mysql select join insert

我说tableA看起来像这样:

colA | colB | colC | colD | 
 1   |  x   |  5   |   v  |
 2   |  y   |  2   |   r  |
 3   |  z   |  4   |   t  | 
 4   |  e   |  8   |   p  |
 5   |  n   |  1   |   m  |
 6   |  f   |  3   |   i  |
 7   |  es  |  8   |   pw |
 8   |  ne  |  5   |   ms |
 9   |  fd  |  3   |   ir |
 10  |  u   |  9   |   gv |
 11  |  y   |  1   |   rh |
 12  |  w   |  4   |   en |

依此类推(大约80,000行)......

我想用tableA中的数据填充tableB,就像这样

colA | colB | colC | colD | colE | colF | colG|
 2   |   x  |   v  |   y  |   r  |   z  |   t | 
 5   |   e  |   p  |   n  |   m  |   f  |   i |
 11  |   u  |   gv |   y  |   rh |   w  |  en |

依此类推(约10,000行)......

如您所见,tableA中tableA.colD< = 2的行已被用作参考,以在tableB中生成新行。

tableA.colD< = 2占用tableB。(colB,colC)的上面的行,tableA.colD< = 2占用tableB。(colF,colG)的行下面的行和tableA.colD< = 2的行使用tableA.colA占用tableB。(colD,colE),其中tableA.colD< = 2用作tableB.colA中的id

我怀疑连接,插入和更新的组合是有序的,但我不知道如何进行这样的任务。使用以下内容,我可以将行作为范围复制到临时表,但这是我得到的:/

CREATE PROCEDURE cant_work_it_out()
BEGIN
SET @final = (select colA from tableA where colD<=2 order by colA desc limit 1);
SET x=0;
REPEAT 
SET @centre = (select colA from tableA where colD<=2 order by colA asc limit x,1);
INSERT INTO temptable 
(select * from tableA where colA= @centre order by colA asc limit 1)
union  
(select * from tableA where colA < @centre order by colA desc limit 1)
union 
(select * from tableA where colA > @centre order by colA asc limit 1);
x=x+1;
UNTIL @centre=@final
END REPEAT
END $$

如何解释如何重新排列数据?

编辑:这不是每三行折叠的问题。要折叠的行将始终出现在colD <= 2

的中心行周围

1 个答案:

答案 0 :(得分:1)

有可能,我完全误解了你实际想要实现的目标,但我会试一试。我已经在循环中省略了选择和插入,因为你已经设法自己做了。

CREATE PROCEDURE possible_to_work_it_out()
BEGIN
SET @start = (SELECT colA FROM tableA WHERE (colA+1)%3=0 ORDER BY colA ASC LIMIT 1);
SET @final = (SELECT colA FROM tableA WHERE (colA+1)%3=0 ORDER BY colA DESC LIMIT 1);
SET @center=@start;
REPEAT 
INSERT INTO temptable 
[...]
@center = @center + 3;
UNTIL @center=@final+3
END REPEAT
END $$

我从表格的简短示例中理解的是,您将tableA的每3行组合在一起形成一行tableB。因此,您只需选择第一个和最后一个三元组,然后以3为步长从开始到结束递增。开始和结束的选择是否实际取决于它(开始+ 1)%3 = 0或任何其他条件是当然完全取决于你。注意:这个循环通过tableA假设,你的colA没有间隙!

如果我误解了您的问题,请提供更多详细信息。从这么短的样本中看模式并不容易。


评论后编辑:(代码应该是自解释的)

CREATE PROCEDURE possible_to_work_it_out()
BEGIN
CREATE TEMPORARY TABLE IF NOT EXISTS tempTable AS (SELECT colA, colD FROM tableA)

SET @center = (SELECT colA FROM tempTable ORDER BY colA ASC LIMIT 1);

REPEAT 
@prev = SELECT colA FROM tableA WHERE colA < @center ORDER BY colA DESC LIMIT 1;
@next = SELECT colA FROM tableA WHERE colA > @center ORDER BY colA ASC LIMIT 1;
INSERT INTO tableB 
(SELECT [...] FROM tableA WHERE colA=@prev)
UNION
(SELECT [...] FROM tableA WHERE colA=@center)
UNION
(SELECT [...] FROM tableA WHERE colA=@next);

@center = SELECT FROM tempTable WHERE colA > @center ORDER BY colA ASC LIMIT 1;
UNTIL @center = NULL
END REPEAT

END $$

但请注意:我现在无法测试,这只是算法。请特别检查创建临时表的详细信息以及最后一个select语句的返回,因为我只是不知道mysql的确切行为。 创建仅包含索引的临时表,然后选择相邻的行,可以容忍colA中的空白。增加数据库系统的负载,但这不应该只是80k行的问题。