Oracle/SQL - 基于参数的动态列

Posted

技术标签:

【中文标题】Oracle/SQL - 基于参数的动态列【英文标题】:Oracle/SQL - Dynamic columns based on parameter 【发布时间】:2018-11-01 15:41:46 【问题描述】:

所以我正在尝试为员工人数报告构建一个数据模型,该模型允许用户选择他希望员工人数计算的内容(动态列)。我尝试查询下面的脚本(这只是一个示例,真正的脚本有几个计数和百分比)并且系统卡在处理中,就像它在循环中一样。我的值列表范围为 1-5。我还尝试制作一个固定的值列表,并将分组列的查询放在值中,这也造成了无休止的处理。有什么想法吗?

(SELECT test1.test1,
    COUNT(DISTINCT id.personid)
    FROM
    table_identifiers id,
    (SELECT DISTINCT
    (CASE WHEN :P_COLUMN = 1 THEN te.ethnicities
    WHEN :P_COLUMN = 2 THEN tc.companyname
    ELSE NULL END) AS test1
    FROM
    table_ethnicities te,
    table_companies tc
    WHERE 1=1

    ) test1
    GROUP BY test1.test1)

【问题讨论】:

除了笛卡尔连接,请注意逗号分隔的FROM 子句不鼓励使用,也不应使用,优先明确列出JOINs(并包括尽可能多的条件)在ON 子句中使用JOIN,而不是作为WHERE 的一部分)。您的部分问题也可能是按动态列分组 - 尽管优化器可能足够聪明以提升常量(需要分析)。否则,您会使用动态 SQL 获得更好的结果,但这更容易出错。 我知道,我这样做更多是为了稍微缩短我的查询并将它们保持在可管理的水平,以快速筛选和定位脚本片段的能力。不幸的是,我为一家大公司工作,该公司喜欢限制我对所有内容的访问,因此我必须在 oracle 提供的网络浏览器桌面上进行编程。即使我在单词上有一些颜色编码,也不要使用漂亮的程序,这会很好,或者是一种将数据隔开但没有的方法。所以我尽量保持简单。 【参考方案1】:

乍一看,你有一个笛卡尔连接在你最inner test1 查询

FROM
    table_ethnicities te,
    table_companies tc
    WHERE 1=1

然后您在 table_identifierstest1 查询之间有第二个 caressian 连接。

FROM
    table_identifiers id,(
...
) test1
    GROUP BY test1.test1)

因此,这是此查询性能低下的潜在原因。

为了解决 test1 查询中的问题,我建议使用 UNION ALL 运算符,例如:

(SELECT test1.test1,
    COUNT(DISTINCT id.personid)
    FROM
    table_identifiers id,
    (SELECT DISTINCT te.ethnicities AS test1
          FROM table_ethnicities te
          WHERE :P_COLUMN = 1
     UNION ALL
     SELECT DISTINCT tc.companyname 
          FROM table_companies tc
          WHERE :P_COLUMN = 2
    ) test1
    GROUP BY test1.test1)

要修复第二个笛卡尔连接,您应该添加连接条件。

【讨论】:

这确实解决了我现在不断加载的问题,由于某种原因,我的 companyname 列并不明显,即使我使用了 DISTINCT 我想知道为什么。但这可能是我自己可以弄清楚的。谢谢:) 嗨@K。莱顿。您有重复项,因为您在 test1 查询的输出和 table_identifiers 表之间没有连接条件。这会产生笛卡尔连接,并随后在最终输出中复制公司名称。

以上是关于Oracle/SQL - 基于参数的动态列的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Oracle SQL 语句中重用动态列?

oracle sql中的动态列

使用动态列 Oracle SQL 查询的数据

基于公共列值Oracle SQL选择多行

基于Oracle SQL中其他列的订单计数

ORAClE sql如何实现行转列?