重塑表,以便日期在MySQL中的列中是连续的

时间:2016-07-26 21:55:58

标签: mysql reshape

我有一个这样的简单表:

| ID | Time1 | Time2 | Time3 |
|----|-------|-------|-------|
| 1  | 2005  |       |       |
| 2  | 2003  | 2004  | 2005  |
| 3  | 2004  |       |       |
| 4  | 2003  | 2005  |       |
| 5  | 2005  |       |       |

是否有一种适度无痛的方式来重塑这张桌子并最终得到这样的桌子?

正如您所看到的,我想在3 TimeN列中排列格式不正确的值,以便它们按顺序排序,并且存在日期不存在的空值。

| ID | Time1 | Time2 | Time3 |
|----|-------|-------|-------|
| 1  |       |       | 2005  |
| 2  | 2003  | 2004  | 2005  |
| 3  |       | 2004  |       |
| 4  | 2003  |       | 2005  |
| 5  |       |       | 2005  |  

我认为必须有一种比我目前正在扩展的50行可怕MySQL更简单的方法。

1 个答案:

答案 0 :(得分:1)

没有神秘的SQL语句可以做到这一点。

您将需要一个SQL语句,为每个列分配值,如下所示:

 UPDATE mysimpletable t
    SET t.Time1 = expr
      , t.Time2 = expr
      , t.Time3 = expr

我建议你先建立一个新表。获取一个SELECT语句,返回您之后的结果。

如果您可以确定每列中的值,那么这将是最简单的。如果2003是您的最低值,并且您希望它出现在Time1列中,如果该值出现在任何TimeN列中,则每个值都固定到特定列,如下所示:

 SELECT s.id
      , IF('2003' IN (s.Time1,s.Time2,s.Time3),'2003',NULL) AS Time1
      , IF('2004' IN (s.Time1,s.Time2,s.Time3),'2004',NULL) AS Time2
      , IF('2005' IN (s.Time1,s.Time2,s.Time3),'2005',NULL) AS Time3
   FROM mysimpletable s
  ORDER BY s.id

如果返回你所追求的结果,假设id列是一个非空的唯一键,我会做:

 CREATE TABLE newtable (PRIMARY KEY (id)) AS SELECT ...

一旦我确定这是正确的,我只会执行更新。

 UPDATE newtable s
   JOIN mysimpletable t
     ON t.id = s.id
    SET t.Time1 = s.Time1
      , t.Time2 = s.Time2
      , t.Time3 = s.Time3

此方法适用于示例数据。但同样,这假设我们知道2003将是存储在Time1中的值,而2004年是存储在Time2等中的值。

可能有一种更简单,更简单的方法。但这是我要采取的方法......我首先使用SELECT语句进行处理,开发返回每个列的值的表达式。然后从该SELECT创建一个临时工作表。然后在确定它是我想要的之后,我会使用工作表作为来源进行更新。

但我也在质疑为什么表的设计方式如此,因此首先需要执行此类更新。