使用动态 PL/SQL 转置具有单行结果的未知列数
Transpose unknown number of columns with single row result using dynamic PL/SQL
我相信一定有一种简单的方法可以实现这一点,只是我还没有弄清楚。我一直在寻找一种方法,但我找不到任何不涉及聚合的方法,
我有一个动态查询 (Oracle),我使用以下形式的配置表在循环中构建:
SELECT
b1.id1,
b2.id2,
...
FROM
table_a a,
table_b b1,
table_b b2,
...
WHERE
a.id = a_variable
AND ( b1.value (+)= a.column1
AND b2.value (+)= a.column2
...);
我总是希望它成为 return 一行,否则会抛出错误。我希望得到这样的结果:
---------------
|ID | VALUE |
---------------
|ID1 | 9 |
|ID2 | 8 |
|ID3 | NULL |
|ID4 | 6 |
|... |
---------------
而不是:
-----------------------------
|ID1 | ID2 | ID3 | ID4 | ...
-----------------------------
| 9 | 8 | NULL| 6 | ...
-----------------------------
提前致谢!!
你提供的信息很少,所以我的回答也只是我前段时间在申请中做的一个例子。当然,这不是您问题的解决方案,但也许它可以让您知道如何去做。
sqlstr := 'WITH t AS '||CHR(13);
sqlstr := sqlstr || '(SELECT START_TIME, WOC_ID, COUNT(WOC_ID) AS COUNT_TRIGGER '||CHR(13);
sqlstr := sqlstr || 'FROM P_KPI_DEF JOIN T_REPORT_KPI ON REKA_WOC_ID = WOC_ID '||CHR(13);
sqlstr := sqlstr || 'WHERE MO_ID = :objId ';
sqlstr := sqlstr || 'AND AGG_LEVEL = :aggLevel ';
sqlstr := sqlstr || 'GROUP BY START_TIME, WOC_ID) '||CHR(13);
sqlstr := sqlstr || 'SELECT * FROM t PIVOT (SUM(COUNT_TRIGGER) AS KPI_COUNT FOR WOC_ID IN (';
FOR aKPI IN (SELECT * FROM P_KPI_DEF) LOOP
sqlstr := sqlstr || aKPI.WOC_ID||' AS '||aKPI.WOC_COLUMN_NAME||',';
END LOOP;
sqlstr := REGEXP_REPLACE(sqlstr, ',$', '))')||CHR(13);
sqlstr := sqlstr || 'ORDER BY 1';
OPEN cur FOR sqlstr USING ...;
只需在动态查询结束时做一个简单的逆透视:
SELECT *
FROM your_query
UNPIVOT INCLUDE NULLS (
"VALUE" FOR id IN (ID1 ,ID2 ,ID3 ,ID4)
)
我相信一定有一种简单的方法可以实现这一点,只是我还没有弄清楚。我一直在寻找一种方法,但我找不到任何不涉及聚合的方法,
我有一个动态查询 (Oracle),我使用以下形式的配置表在循环中构建:
SELECT
b1.id1,
b2.id2,
...
FROM
table_a a,
table_b b1,
table_b b2,
...
WHERE
a.id = a_variable
AND ( b1.value (+)= a.column1
AND b2.value (+)= a.column2
...);
我总是希望它成为 return 一行,否则会抛出错误。我希望得到这样的结果:
---------------
|ID | VALUE |
---------------
|ID1 | 9 |
|ID2 | 8 |
|ID3 | NULL |
|ID4 | 6 |
|... |
---------------
而不是:
-----------------------------
|ID1 | ID2 | ID3 | ID4 | ...
-----------------------------
| 9 | 8 | NULL| 6 | ...
-----------------------------
提前致谢!!
你提供的信息很少,所以我的回答也只是我前段时间在申请中做的一个例子。当然,这不是您问题的解决方案,但也许它可以让您知道如何去做。
sqlstr := 'WITH t AS '||CHR(13);
sqlstr := sqlstr || '(SELECT START_TIME, WOC_ID, COUNT(WOC_ID) AS COUNT_TRIGGER '||CHR(13);
sqlstr := sqlstr || 'FROM P_KPI_DEF JOIN T_REPORT_KPI ON REKA_WOC_ID = WOC_ID '||CHR(13);
sqlstr := sqlstr || 'WHERE MO_ID = :objId ';
sqlstr := sqlstr || 'AND AGG_LEVEL = :aggLevel ';
sqlstr := sqlstr || 'GROUP BY START_TIME, WOC_ID) '||CHR(13);
sqlstr := sqlstr || 'SELECT * FROM t PIVOT (SUM(COUNT_TRIGGER) AS KPI_COUNT FOR WOC_ID IN (';
FOR aKPI IN (SELECT * FROM P_KPI_DEF) LOOP
sqlstr := sqlstr || aKPI.WOC_ID||' AS '||aKPI.WOC_COLUMN_NAME||',';
END LOOP;
sqlstr := REGEXP_REPLACE(sqlstr, ',$', '))')||CHR(13);
sqlstr := sqlstr || 'ORDER BY 1';
OPEN cur FOR sqlstr USING ...;
只需在动态查询结束时做一个简单的逆透视:
SELECT *
FROM your_query
UNPIVOT INCLUDE NULLS (
"VALUE" FOR id IN (ID1 ,ID2 ,ID3 ,ID4)
)