如何在 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);