SQL 行转列时如何应对不同的数据类型 *

有数据库表FIRSTTBL,部分数据如下所示:

ID

PROPERTY

TYPE

STRING

INTEGER

DATETIME

BOLLEAN

XML

1

firstname

NVARCHAR

John

null

null

null

null

1

lastname

NVARCHAR

Doe

null

null

null

null

1

birthdate

DATETIME

null

null

1986-09-16

null

null

1

address

XML

null

null

null

null

eyJh…

1

flag

BIT

null

null

null

1

null

1

number

INT

null

20

null

null

null

2

表中的数据每6条可以转为以下的一条记录,部分结果如下:

ID

FIRSTNAME

LASTANME

BIRTHDAY

ADDRESS

FLAG

NUMBER

1

John

Doe

1986-09-16

eyJh…

1

20

2

 

行转列,将PROPERTY中的各字段值(每6条)作为新列,取STRINGINTEGERDATETIMEBOLLEANXML这几列的非空数据对应新列的数据(转换的同时需要保留各字段的数据类型)

SQL

SELECT

            ID,

            FIRSTNAME,

            ...,

            FLAG = CAST (FLAG AS INT),

            ...

FROM

            (

            SELECT

                        *

            FROM

                        (

                        SELECT

                                    f.ID,

                                    f.PROPERTY,

                                    f.STRING + f."INTEGER" + f.DATETIME + f.BOLLEAN + f.XML AS COLS

                        FROM

                                    FIRSTTBL f)

                        

            PIVOT(

                        min(COLS) FOR PROPERTY IN

                                    (

                                    'firstname' AS firstname,

                                    'lastname' AS lastname,

                                    'birthdate' AS birthdate,

                                    'address' AS address,

                                    'flag' AS flag,

                                    'number' AS "NUMBER"

                                    )

                        )

            )

 

容易看出,任意行的STRINGINTEGERDATETIMEBOLLEANXML中有且仅有一列非空,只需要取第一个非空值,然后按要求行转列即可。对于这题来说,用PIVOT函数行转列本身并不难,但是SQL 中的列需要有统一的数据类型。这题需要先把合并列后的数据转为串,行转列操作后再按实际类型转回来。当列数较多时,SQL写起来就很麻烦了,更难以实现动态需求。

 

用开源集算器的SPL就很容易写:


A

1

=connect("MSSQL")

2

=A1.query@x("SELECT * FROM FIRSTTBL")

3

=A2.pivot(ID;PROPERTY,~.array().m(4:).ifn();"firstname":"FIRSTNAME","lastname":"LASTANME","birthdate":"BIRTHDAY","address":"ADDRESS","flag":"FLAG","number":"NUMBER")

SPL中的同列数据不要求统一数据类型,很容易实现行转列的同时保留数据类型。

 

问答搜集

https://stackoverflow.com/questions/64101227/sql-server-pivot-values-with-different-data-types