在不损失性能的情况下转置 SQL 列
Transpone SQL columns without loss in performance
我用的是SQLServer 2012,我有两个大表,里面有数据,如下:
tableProjects(为简单起见减少了列数)
| ID | Name |
| 1 | Project1 |
| 2 | Project2 |
| … | … |
| N | ProjectN |
tableHours(为简单起见,流程阶段数减少到 3 个)
| ProjectID | ProcessStage | Hours |
| 1 | 1 | 10 |
| 1 | 2 | 20 |
| 1 | 3 | 30 |
| 2 | 1 | 40 |
| 2 | 2 | 50 |
| 2 | 3 | 60 |
| … | … | … |
| N | 1 | 70 |
| N | 2 | 80 |
| N | 3 | 90 |
我需要 select 这些数据,每个 ProcessStage 都有一个单独的列,所以我像这样转换这些数据:
SELECT p.ID, p.Name,
(SELECT Hours FROM tableHours WHERE ProcessStage = 1 AND ProjectID = p.ID) AS Hours1,
(SELECT Hours FROM tableHours WHERE ProcessStage = 2 AND ProjectID = p.ID) AS Hours2,
(SELECT Hours FROM tableHours WHERE ProcessStage = 3 AND ProjectID = p.ID) AS Hours3
FROM tableProjects p
事实上我确实得到了我想要的:
| ID | Name | Hours1 | Hours2 | Hours3 |
| 1 | Project1 | 10 | 20 | 30 |
| 2 | Project2 | 40 | 50 | 60 |
| … | … | … | … | … |
| N | ProjectN | 70 | 80 | 90 |
但在我的案例中,性能非常重要,所以我在考虑是否有更高效的方法来做到这一点。如果你知道,你能告诉我吗?谢谢。
使用条件聚合来透视数据:
select
p.id
, p.Name
, Hours1 = max(case when h.ProcessStage = 1 then h.Hours end)
, Hours2 = max(case when h.ProcessStage = 2 then h.Hours end)
, Hours3 = max(case when h.ProcessStage = 3 then h.Hours end)
from tableProjects p
inner join tableHours h
on h.Projectid = p.id
group by p.id, p.Name
您可以使用动态 sql 自动生成数据透视表所需的列,但既然您说性能非常重要,那么最好尽可能对其进行硬编码。
我用的是SQLServer 2012,我有两个大表,里面有数据,如下:
tableProjects(为简单起见减少了列数)
| ID | Name |
| 1 | Project1 |
| 2 | Project2 |
| … | … |
| N | ProjectN |
tableHours(为简单起见,流程阶段数减少到 3 个)
| ProjectID | ProcessStage | Hours |
| 1 | 1 | 10 |
| 1 | 2 | 20 |
| 1 | 3 | 30 |
| 2 | 1 | 40 |
| 2 | 2 | 50 |
| 2 | 3 | 60 |
| … | … | … |
| N | 1 | 70 |
| N | 2 | 80 |
| N | 3 | 90 |
我需要 select 这些数据,每个 ProcessStage 都有一个单独的列,所以我像这样转换这些数据:
SELECT p.ID, p.Name,
(SELECT Hours FROM tableHours WHERE ProcessStage = 1 AND ProjectID = p.ID) AS Hours1,
(SELECT Hours FROM tableHours WHERE ProcessStage = 2 AND ProjectID = p.ID) AS Hours2,
(SELECT Hours FROM tableHours WHERE ProcessStage = 3 AND ProjectID = p.ID) AS Hours3
FROM tableProjects p
事实上我确实得到了我想要的:
| ID | Name | Hours1 | Hours2 | Hours3 |
| 1 | Project1 | 10 | 20 | 30 |
| 2 | Project2 | 40 | 50 | 60 |
| … | … | … | … | … |
| N | ProjectN | 70 | 80 | 90 |
但在我的案例中,性能非常重要,所以我在考虑是否有更高效的方法来做到这一点。如果你知道,你能告诉我吗?谢谢。
使用条件聚合来透视数据:
select
p.id
, p.Name
, Hours1 = max(case when h.ProcessStage = 1 then h.Hours end)
, Hours2 = max(case when h.ProcessStage = 2 then h.Hours end)
, Hours3 = max(case when h.ProcessStage = 3 then h.Hours end)
from tableProjects p
inner join tableHours h
on h.Projectid = p.id
group by p.id, p.Name
您可以使用动态 sql 自动生成数据透视表所需的列,但既然您说性能非常重要,那么最好尽可能对其进行硬编码。