在DB2中,我们如何将一个简单的"select*fromTABLEfetch first 1 rows only"查询输出行转换为列?
TABLE 名称可能是动态的,因此select中的(*(是必须的。。
TIA征求您的意见和建议。
示例:
来自:
F1 | |
---|---|
ABC |
尝试下面这样的通用表函数
第1个参数是任何有效的SELECT语句文本
第2个参数是要转换的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
简单的答案是你不能
IBM i的Db2中没有任何内容可以对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;
或者,由于您使用的是7.4版,您可以构建并执行一个动态语句,将字段CONCAT
放入字符串列表中,然后使用SPLIT((表函数将列表分解为行。
最后,您可以构建并执行一个动态语句,该语句使用JSON函数来构建一个JSON数组,然后可以使用JSON_TABLE((函数将其分解为行。
但正如强调的那样,在所有情况下,您都需要知道实际SELECT的列和表名。因此需要动态构建语句。
您可以尝试使用LATERAL
select
Key, value
from mytable T,
lateral (values ('F1', t.F1)
, ('F2', t.F2)
, ('F3', t.F3)
) as mypivot(key, value);