Oracle高级联盟

时间:2011-10-25 12:36:35

标签: sql oracle union

是否有任何高级Oracle SQL方法可以解决这种情况?

简化为: 两个查询返回 primary_key_value other_value 。 两个查询总是返回primary_key_value,但other_value可能为null。

那么我如何将这两个查询联合起来以便它总是返回那些具有other_value的行,但是如果两个查询的other_value = null且具有相同的主键,则只返回一行。

我知道这是如此愚蠢的情况。但规格是这样的:)

实施例: 第一个查询:

A  |  B
=======
1  | X
2  | 
3  | 
4  | Z

第二次查询:

A  |  B
=======
1  | Y
2  | 
3  | Z
4  | 

所以结果必须是这样的:

A  |  B
=======
1  | X
1  | Y
2  | 
3  | Z
4  | Z

3 个答案:

答案 0 :(得分:4)

您可以使用分析:

SQL> WITH q1 AS (
  2     SELECT 1 a, 'X' b FROM DUAL UNION ALL
  3     SELECT 2 a, ''  b FROM DUAL UNION ALL
  4     SELECT 3 a, ''  b FROM DUAL UNION ALL
  5     SELECT 4 a, 'Z' b FROM DUAL
  6  ), q2 AS (
  7     SELECT 1 a, 'Y' b FROM DUAL UNION ALL
  8     SELECT 2 a, ''  b FROM DUAL UNION ALL
  9     SELECT 3 a, 'Z' b FROM DUAL UNION ALL
 10     SELECT 4 a, ''  b FROM DUAL
 11  )
 12  SELECT a, b
 13    FROM (SELECT a, b,
 14                 rank() over(PARTITION BY a 
 15                             ORDER BY decode(b, NULL, 2, 1)) rnk
 16             FROM (SELECT * FROM q1
 17                    UNION
 18                   SELECT * FROM q2))
 19   WHERE rnk = 1;

         A B
---------- -
         1 X
         1 Y
         2 
         3 Z
         4 Z

答案 1 :(得分:0)

如果你想使用真正高级的东西,请使用model http://rwijk.blogspot.com/2007/10/sql-model-clause-tutorial-part-one.html 但是,在现实生活中,使用这些东西通常意味着设计不良的数据模型

答案 2 :(得分:0)

另一种观察方式是,您希望列A的并集中的所有可能值然后左外部连接将这些值与列B中的非空值连接,因此在没有非空时仅在B中显示null值显示。
粗略地说:

WITH q1 as (whatever),
     q2 as (whatever)
SELECT All_A.A, BVals.B
FROM (SELECT DISTINCT A FROM (SELECT A FROM q1 UNION SELECT A FROM q2)) All_A,
     (SELECT A,B FROM q1 WHERE B IS NOT NULL
      UNION
      SELECT A,B FROM q2 WHERE B IS NOT NULL) BVals
WHERE All_A.A = BVals.A (+)

同样明确修剪不需要的空值也可以完成相同的工作:

WITH q3 AS (q1_SELECT UNION q2_SELECT)
SELECT A,B
FROM q3 main
WHERE NOT ( B IS NULL AND
            EXISTS (SELECT 1 FROM q3 x WHERE main.A = x.A and x.B IS NOT NULL) )