【发布时间】:2014-08-14 23:52:48
【问题描述】:
我有一些非规范化数据,我正试图对其列进行反透视,希望大家能帮助我找出最好的方法。我已经使用多个联合语句完成了这项工作,但我希望做的是创建一个动态查询,随着更多列添加到表中,它可以一遍又一遍地执行此操作。我的数据看起来像这样:(数字列一直到 50)
| Code | Desc | Code_0 | Desc_0| Period| 1 | 2 | 3 | 4 |
|-------|-------|--------|-------|-------|---------|--------|---------|----------|
| NULL | NULL | NULL | NULL | Date |29-Nov-13|6-Dec-13|13-Dec-13| 20-Dec-13|
|CTR07 |Risk | P1 | Phase1| P | 0.2 | 0.4 | 0.6 | 1.1 |
|CTR07 |Risk | P1 | Phase1| F | 0.2 | 0.4 | 0.6 | 1.1 |
|CTR07 |Risk | P1 | Phase1| A | 0.2 | 0.4 | 0.6 | 1.1 |
|CTR08 |Oper | P1 | Phase1| P | 0.6 | 0.6 | 0.9 | 2.7 |
|CTR08 |Oper | P1 | Phase1| F | 0.6 | 0.6 | 0.9 | 2.7 |
|CTR08 |Oper | P1 | Phase1| A | 0.6 | 0.6 | 0.9 | 2.7 |
列标题是最上面的行。正如您在查看数据时所看到的,有一些奇怪的事情需要处理。
日期字段开始之前的前四个 NULL 列是一个问题。具有数字标题 (1-50) 的每一列代表一周。这样做的问题是,每周不仅有日期字段,而且同一列中还有该周的百分比值。我想让它向下旋转,所以它看起来像这样:
| Code | Desc |Code_0 |Desc_0 | Period| Date |Percent|
|-------|-------|-------|-------|-------|---------|-------|
|CTR07 | Risk | P1 | Phase | P | 11/29/13| 0.2 |
|CTR07 | Risk | P1 | Phase1| F | 11/29/13| 0.2 |
|CTR07 | Risk | P1 | Phase1| A | 11/29/13| 0.2 |
|CTR08 | Oper. | P1 | Phase1| P | 11/29/13| 0.6 |
每周的日期在它自己的列中,百分比按各自的日期分组。
由不同的代码、描述、CODE_0、期间和日期键入。我想将日期与数字列中的百分比分开,然后将数字列放入按日期连接的自己的列中。正如我之前所说,我已经使用 UNION 语句静态地完成了它,但是我想编写某种查询来随着表的扩展而动态地完成它。任何帮助将不胜感激。如果您需要任何其他信息,请告诉我,这是我在 StackOverflow 上的第一个问题,我有两个不错的屏幕截图向您展示,但我在这次交流中还不到 10 岁。仅适用于科幻和奇幻。我知道,对吧?
我在 union 中用于静态创建底部表的代码:
select `Code`, `Desc`, `Code_0`, `Desc_0`, `Period`, (select STR_TO_DATE(`1`, '%d%b%y') from combined_complete where `1` = '29Nov13') as `Date`, `1` as `Percent`
from combined_complete
where period <> 'Date'
union
select `Code`, `Desc`, `Code_0`, `Desc_0`, `Period`, (select STR_TO_DATE(`2`, '%d%b%y') from combined_complete where `2` = '06Dec13') as `Date`, `2`
from combined_complete
where period <> 'Date'
union
select `Code`, `Desc`, `Code_0`, `Desc_0`, `Period`, (select STR_TO_DATE(`3`, '%d%b%y') from combined_complete where `3` = '13Dec13') as `Date`, `3`
from combined_complete
where period <> 'Date'
union
select `Code`, `Desc`, `Code_0`, `Desc_0`, `Period`, (select STR_TO_DATE(`4`, '%d%b%y') from combined_complete where `4` = '20Dec13') as `Date`, `4`
from combined_complete
where period <> 'Date'
【问题讨论】:
-
老实说,我不会尝试使用“纯”SQL 来执行此操作...我宁愿使用另一种编程语言(python、java 等)来读取数据并将其存储在新表
-
无论如何不要使用
UNION请使用UNION ALL,这里不需要联合本身,并且比union all慢