Oracle PL/SQL - 根据条件对不同列进行选择、分组、排序、where-clause 的最佳方法?

Posted

技术标签:

【中文标题】Oracle PL/SQL - 根据条件对不同列进行选择、分组、排序、where-clause 的最佳方法?【英文标题】:Oracle PL/SQL - best way to do select, group-by, order-by, where-clause on different columns, based on a condition? 【发布时间】:2016-06-22 06:59:52 【问题描述】:

您好,我有一个问题需要我根据条件在不同的列上进行选择。我可以在带有不干净的 IF ELSIF 子句的存储过程中实现这一点,但我想知道解决这个问题的最佳方法。这是一个更清楚的例子:

PROCEDURE notSoSmartSelect(type IN VARCHAR, a_filter IN VARCHAR
             , b_filter IN VARCHAR, results OUT SYS_REFCURSER) IS
BEGIN
  IF type = 'A' THEN
    OPEN results FOR 
      SELECT a, sum(val) v FROM sample_table
      GROUP BY a, ORDER BY a;
  ELSIF type = 'B' THEN
    OPEN results FOR 
      SELECT b, a, sum(val) v FROM sample_table
      WHERE a = a_filter
      GROUP BY b, a, ORDER BY a, b;
  ELSIF type = 'C' THEN
    OPEN results FOR 
      SELECT c, b, a, sum(val) v FROM sample_table
      WHERE a = a_filter AND b = b_filter
      GROUP BY c, b, a, ORDER BY a, b, c;
  END IF;
END;

正如您所注意到的,在每种情况下,使用的表都是相同的,但是用于获取、过滤、分组和排序的列不同。

上面的代码看起来很简单,但实际问题有很多分支,并且有多个if-else,这使得代码很脏。有没有一种优雅而干净的方法来解决这个问题?也许是动态 SQL?但我似乎无法找出为此编写动态 sql 的最佳方法。提前致谢。

【问题讨论】:

【参考方案1】:

我不认为这“不干净”。这些查询彼此非常不同,所以我不会尝试将它们合并到一个语句中。

但鉴于它们如此不同(选择不同的列、不同的聚合组、不同的 where 子句),为什么它们都在一个过程中?如果有的话,我会做这三个程序;可能是三个视图。

【讨论】:

【参考方案2】:

这比您想尝试的动态 sql 方法要清晰得多。如前所述,您有许多 IF ELSE 分支,即使构造那么多和"TEST" 那么多条件也会变得非常乏味。

在我看来,您的 refcursor 被任何前端应用程序(如 JAVA)使用,因此最好返回整个输出,然后从该端执行所有操作。

【讨论】:

我更喜欢这样做,但不幸的是大约有 50 万条记录......从数据库中一次获取这么多条记录需要很长时间,而带有 where 子句的查询只返回大约 60 条记录。 那么不幸的是,这是我能想到的唯一方法

以上是关于Oracle PL/SQL - 根据条件对不同列进行选择、分组、排序、where-clause 的最佳方法?的主要内容,如果未能解决你的问题,请参考以下文章

#Oracle#PL/SQL:多个输入的替换变量

oracle 10g pl/sql 有条件的循环选择

创建在循环内输出不同名称的 Oracle PL/SQL 过程

根据 Oracle 10g PL/SQL 中的内容将行转为列

PL/SQL 中 CASE 语句中的堆栈条件

Oracle PL/SQL - 如果不满足条件,则退出开始结束块