重塑 table 以便日期在 MySQL 中的列中按顺序排列
Reshape table so that dates are sequential in columns in MySQL
我有一个简单的 table 像这样:
| ID | Time1 | Time2 | Time3 |
|----|-------|-------|-------|
| 1 | 2005 | | |
| 2 | 2003 | 2004 | 2005 |
| 3 | 2004 | | |
| 4 | 2003 | 2005 | |
| 5 | 2005 | | |
有没有一种适度无痛的方法来重塑这个 table 并最终得到这样的 table?
如您所见,我想在 3 TimeN
列中排列格式不正确的值,以便它们按顺序排列,并且在日期不存在的地方有空值。
| ID | Time1 | Time2 | Time3 |
|----|-------|-------|-------|
| 1 | | | 2005 |
| 2 | 2003 | 2004 | 2005 |
| 3 | | 2004 | |
| 4 | 2003 | | 2005 |
| 5 | | | 2005 |
我想肯定有比我目前扩展的50行可怕的方法更简单的方法MySQL。
没有神秘的 SQL 语句可以做到这一点。
您将需要一个 SQL 语句来为每一列分配值,如下所示:
UPDATE mysimpletable t
SET t.Time1 = expr
, t.Time2 = expr
, t.Time3 = expr
我建议您先构建一个新的 table。得到一个 SELECT 声明,return 是您想要的结果。
如果您可以确定每个列中的值,这将是最简单的。如果 2003 是您的最低值,并且如果该值出现在任何 TimeN 列中,您希望它出现在 Time1 列中,每个值固定到特定列,如下所示:
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
如果 return 是你想要的结果,假设 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 语句来处理它,开发 return 每个列的值的表达式。然后从 SELECT 创建一个临时作品 table。然后在确定它是我想要的之后,我会使用作品 table 作为来源进行更新。
但我也会质疑为什么 table 是这样设计的,因此首先需要执行此类更新。
我有一个简单的 table 像这样:
| ID | Time1 | Time2 | Time3 |
|----|-------|-------|-------|
| 1 | 2005 | | |
| 2 | 2003 | 2004 | 2005 |
| 3 | 2004 | | |
| 4 | 2003 | 2005 | |
| 5 | 2005 | | |
有没有一种适度无痛的方法来重塑这个 table 并最终得到这样的 table?
如您所见,我想在 3 TimeN
列中排列格式不正确的值,以便它们按顺序排列,并且在日期不存在的地方有空值。
| ID | Time1 | Time2 | Time3 |
|----|-------|-------|-------|
| 1 | | | 2005 |
| 2 | 2003 | 2004 | 2005 |
| 3 | | 2004 | |
| 4 | 2003 | | 2005 |
| 5 | | | 2005 |
我想肯定有比我目前扩展的50行可怕的方法更简单的方法MySQL。
没有神秘的 SQL 语句可以做到这一点。
您将需要一个 SQL 语句来为每一列分配值,如下所示:
UPDATE mysimpletable t
SET t.Time1 = expr
, t.Time2 = expr
, t.Time3 = expr
我建议您先构建一个新的 table。得到一个 SELECT 声明,return 是您想要的结果。
如果您可以确定每个列中的值,这将是最简单的。如果 2003 是您的最低值,并且如果该值出现在任何 TimeN 列中,您希望它出现在 Time1 列中,每个值固定到特定列,如下所示:
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
如果 return 是你想要的结果,假设 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 语句来处理它,开发 return 每个列的值的表达式。然后从 SELECT 创建一个临时作品 table。然后在确定它是我想要的之后,我会使用作品 table 作为来源进行更新。
但我也会质疑为什么 table 是这样设计的,因此首先需要执行此类更新。