如何在 DB2 中将 ROW 转置为 Column

发布于 2025-01-10 01:43:08 字数 814 浏览 1 评论 0原文

在 DB2 中,我们如何将一个简单的“select * from TABLE 仅获取前 1 行”查询输出行转置为列?

TABLE 名称可以是动态的,因此 select 中的 (*) 是必须的。TIA

用于您的输入和建议。

示例:

从:

F1F2F3
ABCDEFGHI

到:

F1
ABC
DEF
GHI

in DB2, how can we transpose a simple “select * from TABLE fetch first 1 rows only” query output row into column?

TABLE name could be dynamic so (*) in select is a must..

TIA for ur inputs and suggestion.

Example:

from:

F1F2F3
ABCDEFGHI

to:

F1
ABC
DEF
GHI

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

江城子 2025-01-17 01:43:08

尝试像下面这样的通用表函数。
第一个参数是任何有效的 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 语句以仅返回字符串列并指定简单的列列表:

SELECT * 
FROM TABLE (MYSCHEMA.UNPIVOT (
    'SELECT * FROM (VALUES (CHAR (1), ''2'', CHAR (CURRENT DATE))) T (C1, C2, C3)'
  , 'C2, C3'
)) T

或 将列列表中的每个非字符串列显式转换为 CHAR:

SELECT * 
FROM TABLE (MYSCHEMA.UNPIVOT (
    'SELECT * FROM (VALUES (1, ''2'', CURRENT DATE)) T (C1, C2, C3)'
  , 'CHAR (C1), CHAR (C3)'
)) T

Try a generic table function like below.
The 1-st parameter is whatever valid SELECT statement text.
The 2-nd parameter is a list of column names of this SELECT statement to convert.

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
@

You must either:

construct the SELECT statement to return only string columns and specify a simple column list:

SELECT * 
FROM TABLE (MYSCHEMA.UNPIVOT (
    'SELECT * FROM (VALUES (CHAR (1), ''2'', CHAR (CURRENT DATE))) T (C1, C2, C3)'
  , 'C2, C3'
)) T

or explicitly cast every non-string column in the list of columns to CHAR:

SELECT * 
FROM TABLE (MYSCHEMA.UNPIVOT (
    'SELECT * FROM (VALUES (1, ''2'', CURRENT DATE)) T (C1, C2, C3)'
  , 'CHAR (C1), CHAR (C3)'
)) T
ま昔日黯然 2025-01-17 01:43:08

简短的回答是你不能。
Db2 for IBM i 中没有任何内容可以使用 SELECT * 和动态表来执行此操作。

长答案,您可以构建一个存储过程或用户定义的表函数,动态构建并执行一个老式的语句,如下所示:

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() 表函数来解构将列表分成行。

最后,您可能能够构建并执行动态语句,该语句使用 JSON 函数构建 JSON 数组,然后可以将其解构为具有 JSON_TABLE() 函数。

但正如所强调的,在所有情况下,您都需要知道实际 SELECT 的列名和表名。因此需要动态构建语句。

Short answer is you can't.
There's nothing in Db2 for IBM i that will do this with SELECT * and a dynamic table.

Long answer, you can build a stored procedure or user defined table function that dynamically builds and executes an old school statement that looks like so:

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;

Alternately, since you're on v7.4, you could build and execute a dynamic statement that CONCAT the fields into string list and then use the SPLIT() table function to deconstruct the the list into rows.

Lastly, you might be able to build and execute a dynamic statement that uses the JSON functions to build a JSON array which could then be deconstructed into rows with the JSON_TABLE() function.

But as emphasized, in all cases you'll need to know column and table names for the actual SELECT. Thus the need to dynamically build the statement.

子栖 2025-01-17 01:43:08

您可以尝试使用横向

select 
   Key, value
from mytable T,
      lateral (values ('F1', t.F1)
                      , ('F2', t.F2) 
                      , ('F3', t.F3)
                      ) as mypivot(key, value);

You can try with LATERAL

select 
   Key, value
from mytable T,
      lateral (values ('F1', t.F1)
                      , ('F2', t.F2) 
                      , ('F3', t.F3)
                      ) as mypivot(key, value);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文