将特定列转置为单行
Transpose specific column into single row
我有以下顺序的车辆路径table
Vehicle_ID
Vehicle Path
1
101
1
55
1
136
2
50
2
65
2
75
3
101
3
105
3
110
3
125
我想要如下格式的结果。
Vehicle_ID
Path1
Path2
Path3
Path4
1
101
55
136
2
50
65
75
3
101
105
110
125
我尝试了 pivot 方法,但无法得到如上所示的结果。
请注意,没有第三列维护路径值的实际相对顺序。假设这个顺序无关紧要,我们可以借助 ROW_NUMBER
:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY Vehicle_ID
ORDER BY Vehicle_ID) rn
FROM yourTable
)
SELECT
Vehicle_ID,
MAX(CASE WHEN rn = 1 THEN [Vehicle Path] END) AS Path1,
MAX(CASE WHEN rn = 2 THEN [Vehicle Path] END) AS Path2,
MAX(CASE WHEN rn = 3 THEN [Vehicle Path] END) AS Path3,
MAX(CASE WHEN rn = 4 THEN [Vehicle Path] END) AS Path4
FROM cte
GROUP BY
Vehicle_ID
ORDER BY
Vehicle_ID;
另一种方式,假设 SQL Server 2017 或更高版本(并且您不关心任何给定 Vehicle_ID
的第 5 行和后面的行):
;WITH cte AS
(
SELECT Vehicle_ID,
y = '["' + STRING_AGG(Vehicle_Path, '","') + '"]'
FROM dbo.VehicleInfo
GROUP BY Vehicle_ID
)
SELECT Vehicle_ID,
Path1 = JSON_VALUE(cte.y, '$[0]'),
Path2 = JSON_VALUE(cte.y, '$[1]'),
Path3 = JSON_VALUE(cte.y, '$[2]'),
Path4 = JSON_VALUE(cte.y, '$[3]')
FROM cte;
为了完整起见,PIVOT
版本应该是这样的:
SELECT p.Vehicle_ID, p.[1] AS Path1, p.[2] AS Path3, p.[3] AS Path3, p.[4] AS Path4
FROM (
SELECT Vehicle_ID, Vehicle_Path, ROW_NUMBER() OVER (PARTITION BY Vehicle_ID ORDER BY Vehicle_ID) ix
FROM dbo.VehicleInfo
) AS s
PIVOT (
AVG(Vehicle_Path)
FOR ix IN ([1], [2], [3], [4])
) as p;
当然,Tim Biegeleisen 的回答中提到的顺序警告也适用于此解决方案(就像任何其他解决方案一样)。
我有以下顺序的车辆路径table
Vehicle_ID | Vehicle Path |
---|---|
1 | 101 |
1 | 55 |
1 | 136 |
2 | 50 |
2 | 65 |
2 | 75 |
3 | 101 |
3 | 105 |
3 | 110 |
3 | 125 |
我想要如下格式的结果。
Vehicle_ID | Path1 | Path2 | Path3 | Path4 |
---|---|---|---|---|
1 | 101 | 55 | 136 | |
2 | 50 | 65 | 75 | |
3 | 101 | 105 | 110 | 125 |
我尝试了 pivot 方法,但无法得到如上所示的结果。
请注意,没有第三列维护路径值的实际相对顺序。假设这个顺序无关紧要,我们可以借助 ROW_NUMBER
:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY Vehicle_ID
ORDER BY Vehicle_ID) rn
FROM yourTable
)
SELECT
Vehicle_ID,
MAX(CASE WHEN rn = 1 THEN [Vehicle Path] END) AS Path1,
MAX(CASE WHEN rn = 2 THEN [Vehicle Path] END) AS Path2,
MAX(CASE WHEN rn = 3 THEN [Vehicle Path] END) AS Path3,
MAX(CASE WHEN rn = 4 THEN [Vehicle Path] END) AS Path4
FROM cte
GROUP BY
Vehicle_ID
ORDER BY
Vehicle_ID;
另一种方式,假设 SQL Server 2017 或更高版本(并且您不关心任何给定 Vehicle_ID
的第 5 行和后面的行):
;WITH cte AS
(
SELECT Vehicle_ID,
y = '["' + STRING_AGG(Vehicle_Path, '","') + '"]'
FROM dbo.VehicleInfo
GROUP BY Vehicle_ID
)
SELECT Vehicle_ID,
Path1 = JSON_VALUE(cte.y, '$[0]'),
Path2 = JSON_VALUE(cte.y, '$[1]'),
Path3 = JSON_VALUE(cte.y, '$[2]'),
Path4 = JSON_VALUE(cte.y, '$[3]')
FROM cte;
为了完整起见,PIVOT
版本应该是这样的:
SELECT p.Vehicle_ID, p.[1] AS Path1, p.[2] AS Path3, p.[3] AS Path3, p.[4] AS Path4
FROM (
SELECT Vehicle_ID, Vehicle_Path, ROW_NUMBER() OVER (PARTITION BY Vehicle_ID ORDER BY Vehicle_ID) ix
FROM dbo.VehicleInfo
) AS s
PIVOT (
AVG(Vehicle_Path)
FOR ix IN ([1], [2], [3], [4])
) as p;
当然,Tim Biegeleisen 的回答中提到的顺序警告也适用于此解决方案(就像任何其他解决方案一样)。