sql将列转换为行

jtjikinw  于 2021-08-01  发布在  Java
关注(0)|答案(2)|浏览(402)

我要执行以下转换:

  1. Seniority Price Rating
  2. ---------------------------
  3. 1 P1 R1
  4. 2 P2 R2
  5. 3 P3 R3

  1. Value RowId ColId
  2. ------------------
  3. 1 0 0
  4. P1 0 1
  5. R1 0 2
  6. 2 1 0
  7. P2 1 1
  8. R2 1 2
  9. 3 2 0
  10. P3 2 1
  11. R3 2 2

如果可能的话,我希望在转换表中也保留字段名,即rowid=0的所有行都将添加前辈作为字段,rowid=1将包含price,依此类推。

ercv8c1e

ercv8c1e1#

这里有一个使用json的选项,如果2016+xml版本可用于旧版本。
例子

  1. Declare @YourTable Table ([Seniority] varchar(50),[Price] varchar(50),[Rating] varchar(50))
  2. Insert Into @YourTable Values
  3. (1,'P1','R1')
  4. ,(2,'P2','R2')
  5. ,(3,'P3','R3')
  6. Select B.Value
  7. ,A.RowID
  8. ,B.ColID
  9. From (Select *
  10. ,RowID = row_number() over (order by (select null)) - 1
  11. From @YourTable --<<< Replace with virtually any table.
  12. ) A
  13. Cross Apply (
  14. Select *
  15. ,ColID = row_number() over (order by (select null)) - 1
  16. From OpenJson( (Select A.* For JSON Path,Without_Array_Wrapper,INCLUDE_NULL_VALUES ) )
  17. Where [Key] not in ('RowID')
  18. ) B

退货

编辑-只是为了好玩,xml版本

  1. Select C.Value
  2. ,A.RowID
  3. ,C.ColID
  4. From (Select *
  5. ,RowID = row_number() over (order by (select null)) - 1
  6. From @YourTable
  7. ) A
  8. Cross Apply ( values ( convert(xml,(Select A.* for XML RAW)) ) ) B(XMLData)
  9. Cross Apply (
  10. Select ColID = row_number() over( order by (select null)) - 1
  11. ,Value = xAttr.value('.','varchar(max)')
  12. From XMLData.nodes('//@*') xNode(xAttr)
  13. Where xAttr.value('local-name(.)', 'varchar(100)') not in ('RowID')
  14. ) C

edit—允许空值的xml版本

  1. Declare @YourTable Table ([Seniority] varchar(50),[Price] varchar(50),[Rating] varchar(50))
  2. Insert Into @YourTable Values
  3. (1,'P1','R1')
  4. ,(2,'P2','R2')
  5. ,(3,NULL,'R3') -- Forced a NULL value
  6. Select C.Value
  7. ,A.RowID
  8. ,C.ColID
  9. From (Select *
  10. ,RowID = row_number() over (order by (select null)) - 1
  11. From @YourTable
  12. ) A
  13. Cross Apply ( values ( convert(xml,(Select A.* for XML RAW,ELEMENTS XSINIL)) ) ) B(XMLData)
  14. Cross Apply (
  15. Select Item = attr.value('local-name(.)','varchar(100)')
  16. ,Value = attr.value('.','varchar(max)')
  17. ,ColID = row_number() over (order by (select null)) - 1
  18. From XMLData.nodes('/row') as C1(nd)
  19. Cross Apply C1.nd.nodes('./*') as C2(attr)
  20. Where attr.value('local-name(.)','varchar(100)') not in ('RowID')
  21. ) C

退货

  1. Value RowID ColID
  2. 1 0 0
  3. P1 0 1
  4. R1 0 2
  5. 0 0 3
  6. 2 1 0
  7. P2 1 1
  8. R2 1 2
  9. 1 1 3
  10. 3 2 0
  11. 2 1 --<< Notice NULLs return as Empty Strings
  12. R3 2 2
  13. 2 2 3
展开查看全部
dddzy1tm

dddzy1tm2#

一般来说, union all 作品:

  1. select seniority, 'seniority' as which, seniority - 1, 0
  2. from t
  3. union all
  4. select p1, 'p1' as which, seniority - 1, 1
  5. from t
  6. union all
  7. select r1, 'r1' as which, seniority - 1, 2
  8. from t;

相关问题