从数据库表中展平数据

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从数据库表中展平数据相关的知识,希望对你有一定的参考价值。

我有表格形式的数据:

Grade |  TimeInterval |  SubjectName
1        0               History
1        1               Chemistry
1        3               Biology
2        0               Maths
2        2               Biology
2        3               History
3        0               Biology
3        1               History
3        2               Chemistry
3        3               Maths

我想将上述数据转换成以下格式,最好的方法是什么。

Grade TimeInterval0 TimeInterval1 TimeInterval2 TimeInterval3
1     History       Chemistry     Empty         Biology
2     Maths         Empty          Biology      History
3     Biology       History        Chemistry    Maths

我不知道是否可以直接使用PIVOT转换,因为原始源数据中的TimeInterval将变为0,1,2而在我的展平目标表中,列名称被指定为TimeInterval0,TimeInterval1,TimeInterval2等。

我无法更改架构,因为它已经有很多数据,而且许多其他表彼此相互关联。

答案

您可以随时进行手动转轴。这允许您控制列名等,但您必须自己完成所有的数据透视工作。像这样的东西

Select G.Grade
    , Int0.SubjectName as TimeInterval0
    , Int1.SubjectName as TimeInterval1
    , Int2.SubjectName as TimeInterval2
    , Int3.SubjectName as TimeInterval3
from (Select distinct Grade from SourceTable) G
    left outer join SourceTable Int0 on Int0.Grade = G.Grade and Int0.TimeInterval = 0
    left outer join SourceTable Int1 on Int1.Grade = G.Grade and Int1.TimeInterval = 1
    left outer join SourceTable Int2 on Int2.Grade = G.Grade and Int2.TimeInterval = 2
    left outer join SourceTable Int3 on Int3.Grade = G.Grade and Int3.TimeInterval = 3
另一答案

您始终可以使用外部查询中的列别名重命名列。我在这里使用CTE。

IF OBJECT_ID('tempdb..#temp') IS NOT NULL DROP TABLE #temp;
CREATE TABLE #temp (Grade INT,  TimeInterval INT, SubjectName VARCHAR(100))

INSERT #temp
(
    Grade,
    TimeInterval,
    SubjectName
)
VALUES
    (1,        0,               'History    '),
    (1,        1,               'Chemistry  '),
    (1,        3,               'Biology    '),
    (2,        0,               'Maths      '),
    (2,        2,               'Biology    '),
    (2,        3,               'History    '),
    (3,        0,               'Biology    '),
    (3,        1,               'History    '),
    (3,        2,               'Chemistry  '),
    (3,        3,               'Maths      ');


WITH pivoted AS (
   SELECT * 
   FROM #temp
   PIVOT ( 
       MAX(SubjectName) FOR TimeInterval IN ([0], [1], [2], [3])
   ) pvt
)
SELECT grade,
       [TimeInterval0] = pivoted.[0],
       [TimeInterval1] = pivoted.[1],
       [TimeInterval2] = pivoted.[2],
       [TimeInterval3] = pivoted.[3]
FROM pivoted
另一答案

间隔时间为0-15,但将来会增加

你需要一个dynamic pivot

CREATE TABLE SampleData (Grade INT,  TimeInterval INT, SubjectName VARCHAR(100))

INSERT SampleData
(
    Grade,
    TimeInterval,
    SubjectName
)
VALUES
    (1,        0,               'History    '),
    (1,        1,               'Chemistry  '),
    (1,        3,               'Biology    '),
    (2,        0,               'Maths      '),
    (2,        2,               'Biology    '),
    (2,        3,               'History    '),
    (3,        0,               'Biology    '),
    (3,        1,               'History    '),
    (3,        2,               'Chemistry  '),
    (3,        3,               'Maths      ');

DECLARE @cols nvarchar(max)

SELECT @cols = STUFF(
                    (SELECT DISTINCT CONCAT(',[', t.TimeInterval, ']') FROM SampleData t FOR XML PATH (''))
                   ,1,1,'')

DECLARE @headers nvarchar(max)

SELECT @headers = STUFF(
                    (SELECT DISTINCT CONCAT(', [' , t.TimeInterval , '] AS [TimeInterval' , t.TimeInterval, ']') FROM SampleData t FOR XML PATH (''))
                   ,1,1,'')

DECLARE @query nvarchar(max) = N'Select [Grade],  ' + @headers + 
        ' FROM 
         (
            SELECT Grade, TimeInterval, SubjectName FROM  SampleData
         ) src
         PIVOT
         (
            MAX(SubjectName) FOR TimeInterval IN ('+ @cols+ ')
         ) pvt
        '
PRINT @query

EXEC (@query)

DROP TABLE SampleData

在这里演示http://rextester.com/LIW80994

以上是关于从数据库表中展平数据的主要内容,如果未能解决你的问题,请参考以下文章

在powershell中展平数组

使用 SQL 将 XML 结构转置/展平到列

如何在 Azure 流分析中展平嵌套的 json 数据

无法从片段中的 SQLite 获取数据

如何将数据从 BottomSheetDialogFragment 返回到父片段

具有数组和字典混合的横向展平雪管数据