【发布时间】:2020-08-26 13:48:36
【问题描述】:
首先,我想感谢您光临并花费您宝贵的时间来查看我的问题。
我在一个 Oracle 数据库中有 2 个不同的表。
第一个表包含有关另一个表中存在的列的元数据。将第一个 (COL_TAB) 表视为 Oracle 默认提供的 ALL_TAB_COLS 的自定义版本。
COL_TAB
----------------------------------------------
| TABLE_NAME | COL_NAME | COL_DESC |
----------------------------------------------
| TABLE1 | TAB1_COL_2 | TABLE 1 COLUMN 2 |
| TABLE1 | TAB1_COL_4 | TABLE 1 COLUMN 4 |
| TABLE1 | TAB1_COL_3 | TABLE 1 COLUMN 3 |
| TABLE1 | TAB1_COL_5 | |
| TABLE1 | TAB1_COL_1 | TABLE 1 COLUMN 1 |
----------------------------------------------
TABLE1
--------------------------------------------------------------------
| TAB1_COL_3 | TAB1_COL_1 | TAB1_COL_5 | TAB1_COL_2 |
--------------------------------------------------------------------
| TAB1_COL3_DATA1 | TAB1_COL1_DAT | TAB1_COL5_DAT2 | TAB1_COL2_DAT |
| TAB1_COL3_DATA2 | TAB1_COL1_DAT | TAB1_COL5_DAT1 | TAB1_COL2_DAT |
| TAB1_COL3_DATA3 | TAB1_COL1_DAT | TAB1_COL5_DAT3 | TAB1_COL2_DAT |
--------------------------------------------------------------------
我想将数据显示为 2 个不同的输出:
FIRST OUTPUT:
------------------------------------------------------------------------------------------------
| TABLE 1 COLUMN 3 | TABLE 1 COLUMN 1 | TAB1_COL_5 | TABLE 1 COLUMN 2 | TABLE 1 COLUMN 4 |
------------------------------------------------------------------------------------------------
-> 如果 COL_DESC 为空白或 null,则需要在输出中显示 COL_NAME。 -> "TABLE 1 COLUMN 3" 和 "TABLE 1 COLUMN 1" 总是需要显示为第 1 列和第 2 列,然后是其余列。 -> 如果 COL_TAB 表中定义的任何列未在 TABLE1 中使用,则需要在输出的最后一列显示这样的列, 例如,TAB1_COL_4 没有在 TABLE1 中使用,所以它显示在最后。
SECOND OUTPUT:
------------------------------------------------------------------------------------------------
| TAB1_COL3_DATA1 | TAB1_COL1_DAT | TAB1_COL5_DAT2 | TAB1_COL2_DAT | |
| TAB1_COL3_DATA2 | TAB1_COL1_DAT | TAB1_COL5_DAT1 | TAB1_COL2_DAT | |
| TAB1_COL3_DATA3 | TAB1_COL1_DAT | TAB1_COL5_DAT3 | TAB1_COL2_DAT | |
------------------------------------------------------------------------------------------------
-> 第二个输出中列的顺序需要与第一输出中显示的列的顺序同步。
我确实尝试了以下查询来显示第一个输出,但它不起作用(我确定它不正确):
SELECT NVL(COL_DESC, COL_NAME) AS COL_TEXT
FROM COL_TAB
WHERE TABLE_NAME = 'TABLE1'
PIVOT(MIN(COL_TEXT)
FOR COL_TEXT IN (SELECT COL_NAME FROM COL_TAB WHERE TABLE_NAME = 'TABLE1'));
如果有任何不清楚的地方,请告诉我。我会尽力再解释一遍。再次感谢您提前提供的帮助。
【问题讨论】:
-
您将需要动态 SQL 来用于第一个输出的数据透视(因为您不能在数据透视子句中进行选择,除非您想要 XML 输出),以及获取列排序在第二个输出中。但是为什么你想要单独的输出,应该如何格式化和返回这些输出 - 你用 PL/SQL 标记所以你在考虑
dbms_output或单独的查询 - 在这种情况下需要枢轴吗?您是否真的想要一个包含自定义列标题的表格数据的结果集? -
还有列顺序是怎么确定的?您提到了前两列,最后提到了不匹配的列;但是这些应该以什么顺序出现?所有匹配的列都应该按
column_id的顺序排列,还是只是前两个(这看起来不是很通用)?如果有多个不匹配的列,这些列是如何排序的?这个数据模型看起来很奇怪,但即便如此似乎应该有一个等价的column_id或tab_cols中的某个位置标记。 -
是的,我同意需要动态 SQL。数据将在 3rd 方应用程序中使用,这需要列标题作为一个数据集,表数据作为另一个数据集,这就是我将其标记为 PL/SQL 的原因。
-
就列顺序而言,考虑到上面的示例数据,“TABLE 1 COLUMN 3”和“TABLE 1 COLUMN 1”总是需要显示为第1列和第2列,然后是匹配的列,然后是不匹配的列。
-
但是以什么顺序匹配(和不匹配)列?还是没关系,只要两个输出一致?为什么这两个不同 - 其他表的结构与
table1不同?