如何在 DB2 中将 ROW 转置为 Column
How to transpose ROW to Column in DB2
在 DB2 中,我们如何转置一个简单的“select * from TABLE fetch first 1 rows only”查询输出行成列?
TABLE 名称可以是动态的,所以 select 中的 (*) 是必须的..
TIA 征求您的意见和建议。
示例:
来自:
F1
F2
F3
ABC
DEF
GHI
至:
F1
ABC
DEF
GHI
简短的回答是你不能。
Db2 for IBM i 中没有任何东西可以使用 SELECT *
和动态 table.
来执行此操作
长答案,您可以构建一个存储过程或用户定义的table函数,动态构建和执行一个看起来像这样的老式语句:
with firstRow as
(select F1, F2, F3 from table fetch first row only)
select F1
from firstRow
UNION ALL
select F2
from firstRow
UNION ALL
select F3
from firstRow;
或者,由于您使用的是 v7.4,您可以构建并执行动态语句,将 CONCAT
字段放入字符串列表,然后使用 SPLIT() table function 将列表解构为行。
最后,您可以构建并执行一个动态语句,该语句使用 JSON 函数构建一个 JSON 数组,然后可以使用 JSON_TABLE() 函数解构为行。
但正如所强调的,在所有情况下,您都需要知道实际 SELECT 的列和 table 名称。因此需要动态构建语句。
尝试如下通用 table 函数。
第一个参数是任何有效的 SELECT 语句文本。
第二个参数是要转换的 SELECT 语句的列名列表。
CREATE OR REPLACE FUNCTION MYSCHEMA.UNPIVOT (P_STMT VARCHAR (32000), P_COLLIST VARCHAR (100))
RETURNS TABLE (C VARCHAR (100))
BEGIN
DECLARE SQLCODE INT;
DECLARE V_VAL VARCHAR (100);
DECLARE C1 CURSOR FOR S1;
PREPARE S1 FROM 'SELECT V.C_ FROM (' || P_STMT || '), TABLE (VALUES ' || P_COLLIST || ') V (C_)';
OPEN C1;
L1: LOOP
FETCH C1 INTO V_VAL;
IF SQLCODE = 100 THEN LEAVE L1; END IF;
PIPE (V_VAL);
END LOOP L1;
CLOSE C1;
RETURN;
END
@
您必须:
将 SELECT 语句构造为 return 仅字符串列并指定一个简单的列列表:
SELECT *
FROM TABLE (MYSCHEMA.UNPIVOT (
'SELECT * FROM (VALUES (CHAR (1), ''2'', CHAR (CURRENT DATE))) T (C1, C2, C3)'
, 'C2, C3'
)) T
或将列列表中的每个 non-string 列显式转换为 CHAR:
SELECT *
FROM TABLE (MYSCHEMA.UNPIVOT (
'SELECT * FROM (VALUES (1, ''2'', CURRENT DATE)) T (C1, C2, C3)'
, 'CHAR (C1), CHAR (C3)'
)) T
你可以试试 LATERAL
select
Key, value
from mytable T,
lateral (values ('F1', t.F1)
, ('F2', t.F2)
, ('F3', t.F3)
) as mypivot(key, value);
在 DB2 中,我们如何转置一个简单的“select * from TABLE fetch first 1 rows only”查询输出行成列?
TABLE 名称可以是动态的,所以 select 中的 (*) 是必须的..
TIA 征求您的意见和建议。
示例:
来自:
F1 | F2 | F3 |
---|---|---|
ABC | DEF | GHI |
至:
F1 |
---|
ABC |
DEF |
GHI |
简短的回答是你不能。
Db2 for IBM i 中没有任何东西可以使用 SELECT *
和动态 table.
长答案,您可以构建一个存储过程或用户定义的table函数,动态构建和执行一个看起来像这样的老式语句:
with firstRow as
(select F1, F2, F3 from table fetch first row only)
select F1
from firstRow
UNION ALL
select F2
from firstRow
UNION ALL
select F3
from firstRow;
或者,由于您使用的是 v7.4,您可以构建并执行动态语句,将 CONCAT
字段放入字符串列表,然后使用 SPLIT() table function 将列表解构为行。
最后,您可以构建并执行一个动态语句,该语句使用 JSON 函数构建一个 JSON 数组,然后可以使用 JSON_TABLE() 函数解构为行。
但正如所强调的,在所有情况下,您都需要知道实际 SELECT 的列和 table 名称。因此需要动态构建语句。
尝试如下通用 table 函数。
第一个参数是任何有效的 SELECT 语句文本。
第二个参数是要转换的 SELECT 语句的列名列表。
CREATE OR REPLACE FUNCTION MYSCHEMA.UNPIVOT (P_STMT VARCHAR (32000), P_COLLIST VARCHAR (100))
RETURNS TABLE (C VARCHAR (100))
BEGIN
DECLARE SQLCODE INT;
DECLARE V_VAL VARCHAR (100);
DECLARE C1 CURSOR FOR S1;
PREPARE S1 FROM 'SELECT V.C_ FROM (' || P_STMT || '), TABLE (VALUES ' || P_COLLIST || ') V (C_)';
OPEN C1;
L1: LOOP
FETCH C1 INTO V_VAL;
IF SQLCODE = 100 THEN LEAVE L1; END IF;
PIPE (V_VAL);
END LOOP L1;
CLOSE C1;
RETURN;
END
@
您必须:
将 SELECT 语句构造为 return 仅字符串列并指定一个简单的列列表:
SELECT *
FROM TABLE (MYSCHEMA.UNPIVOT (
'SELECT * FROM (VALUES (CHAR (1), ''2'', CHAR (CURRENT DATE))) T (C1, C2, C3)'
, 'C2, C3'
)) T
或将列列表中的每个 non-string 列显式转换为 CHAR:
SELECT *
FROM TABLE (MYSCHEMA.UNPIVOT (
'SELECT * FROM (VALUES (1, ''2'', CURRENT DATE)) T (C1, C2, C3)'
, 'CHAR (C1), CHAR (C3)'
)) T
你可以试试 LATERAL
select
Key, value
from mytable T,
lateral (values ('F1', t.F1)
, ('F2', t.F2)
, ('F3', t.F3)
) as mypivot(key, value);