如何使用相同的Select语句获取不同的表列

时间:2017-04-10 16:46:53

标签: oracle plsql oracle12c

你有一个包含9列具有相同数据类型的表(都是百分比值)。我尝试在PL \ SQL函数中创建一个Select语句,以返回3的元组,具体取决于外部参数值。

在语法上,类似这样:

WITH tmp
     AS (SELECT '1' col1,
                '2' col2,
                '3' col3,
                '4' col4,
                '5' col5,
                '6' col6,
                '7' col7,
                '8' col8,
                '9' col9
           FROM DUAL
         UNION
         SELECT '10' col1,
                '20' col2,
                '30' col3,
                '40' col4,
                '50' col5,
                '60' col6,
                '70' col7,
                '80' col8,
                '90' col9
           FROM DUAL
         UNION
         SELECT '100' col1,
                '200' col2,
                '300' col3,
                '400' col4,
                '500' col5,
                '600' col6,
                '700' col7,
                '800' col8,
                '900' col9
           FROM DUAL)
SELECT CASE
           WHEN externaparameter = 1 THEN (col1, col2, col3)
           WHEN externaparameter = 2 THEN (col4, col5, col6)
           WHEN externaparameter = 3 THEN (col7, col8, col9)
       END
  INTO var1, var2, var3
  FROM tmp;

我有两个解决方案:

为每列实施CASE语句。但它会创建一个很大的选择声明,可能会令人困惑。

SELECT CASE
           WHEN externaparameter = 1 THEN col1
           WHEN externaparameter = 2 THEN col4
           WHEN externaparameter = 3 THEN col7
       END,
       CASE
           WHEN externaparameter = 1 THEN col2
           WHEN externaparameter = 2 THEN col5
           WHEN externaparameter = 3 THEN col8
       END,
       CASE
           WHEN externaparameter = 1 THEN col3
           WHEN externaparameter = 2 THEN col6
           WHEN externaparameter = 3 THEN col9
       END
  INTO var1, var2, var3
  FROM tmp;

或者,使用union实现三个select语句。但我的原始查询有几个WHERE条件,对于这种情况,我需要重复它们。

SELECT a, b, c
  INTO var1, var2, var3
  FROM (SELECT col1 a, col2 b, col3 c
          FROM tmp
         WHERE externalparameter = 1
        UNION
        SELECT col4 a, col5 b, col6 c
          FROM tmp
         WHERE externalparameter = 2
        UNION
        SELECT col7 a, col8 b, col9 c
          FROM tmp
         WHERE externalparameter = 3)

我是否有针对此问题的更干净的Select语句?每种解决方案的优点和缺点是什么?

1 个答案:

答案 0 :(得分:1)

如果您无法在运行时根据externalparameter有选择地运行三个单独查询中的一个,则使用case表达式的选项1是更清晰的解决方案。

union解决方案的问题:

  1. 检查生成的查询计划是否确定,但我想它会执行三个单独的select语句,尽管它们是互斥的。 (除非12c比查询优化要聪明得多,否则我说到目前为止。)这是因为该计划可能会重复使用,因此计划必须包括所有三个选项,以便在所有情况下都有正确的选择。
  2. union版本包含一个隐式的distinct,如果第一个版本中的内容已经不同,则可以添加工作。或者更改结果与第一个版本。
  3. 动态SQL有时会在这种情况下使用,但我认为有选择地运行三个静态语句比构建动态SQL字符串更好。