【问题标题】:Oracle Dynamic Join ChallengeOracle 动态连接挑战
【发布时间】:2009-10-01 16:16:54
【问题描述】:

编辑: 简单得多的例子。 (原标题:Oracle 列注入)

目标:完成下面的查询生成以下结果?

目的:创建一个依赖于表中现有列的列,而不将该表放在子查询中。

规则:

  1. 重组查询以将 tbl 放入子查询中不是一种选择。
  2. 查询必须使用a,b->1; x->2; y->3,而不是简单地加入1,1,2,1,3
  3. 不得修改子查询tbl

 

SELECT val, cat
  FROM (SELECT 'a' val FROM DUAL  UNION ALL
        SELECT 'b' val FROM DUAL  UNION ALL
        SELECT 'x' val FROM DUAL  UNION ALL
        SELECT 'b' val FROM DUAL  UNION ALL
        SELECT 'y' val FROM DUAL) tbl
   ... JOIN ( ... ) ON ...

 val | cat
-----+-----
 'a' |  1
 'b' |  1
 'x' |  2
 'b' |  1
 'y' |  3

好吧,我已经做到了(如下),但我无法添加第二个 LEFT JOIN。

SELECT val, cat
  FROM (SELECT 'a' val FROM DUAL  UNION ALL
        SELECT 'b' val FROM DUAL  UNION ALL
        SELECT 'x' val FROM DUAL  UNION ALL
        SELECT 'b' val FROM DUAL  UNION ALL
        SELECT 'y' val FROM DUAL) tbl
   LEFT JOIN ( SELECT 1 cat FROM DUAL ) ON val in ('a','b')

 val | cat
-----+-----
 'a' |  1
 'b' |  1
 'x' |  
 'b' |  1
 'y' |  

【问题讨论】:

    标签: sql oracle plsql oracle9i


    【解决方案1】:
    SELECT tbl.val, map.cat
      FROM (SELECT 'a' val FROM DUAL  UNION
            SELECT 'b' val FROM DUAL  UNION
            SELECT 'x' val FROM DUAL  UNION
            SELECT 'b' val FROM DUAL  UNION
            SELECT 'y' val FROM DUAL) tbl
       LEFT JOIN ( SELECT 'a' val, 1 cat FROM DUAL UNION
                   SELECT 'b' val, 1 cat FROM DUAL UNION
                   SELECT 'x' val, 2 cat FROM DUAL UNION
                   SELECT 'y' val, 3 cat FROM DUAL ) map ON map.val = tbl.val
    

    从您的示例中,我怀疑您的意思是使用 UNION ALL 而不是 UNION(为了让 val = 'b' 的 2 行出现在结果中)。

    您的“我已经走了这么远”的示例甚至没有按书面形式运行——它需要在 IN 列表周围加上括号——即使你修复了它,它也不会产生你显示的输出。

    【讨论】:

    • 你快到了。我更喜欢一个解决方案,我可以将同一 cat 的成员放入列表中,因为在我的实际示例中,cat 中的 val 列表约为 30。
    • 你为什么不创建一个将值映射到类别的实际表,然后加入呢?
    • ...呃,我知道有一个简单的解决方案。