2011-10-25 67 views
0

是否有任何先进的Oracle SQL方法来解决这种情况?Oracle高级联盟

简体: 两个查询返回primary_key_valueother_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 

回答

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 
+0

+1不错的使用分析:-) – Yahia

+0

的谢谢你,它的工作:) –

+0

只有一个问题:我不能在q1和q2中使用where子句。我必须把它放到最高层,然后我们遇到性能问题。它在q1和q2查询中进行全表扫描......或者至少默认情况下它没有任何优化器提示。 –

0

另一种方式来看待这就是你想要的所有可能的值从列A的联合然后离开外部外部将这些与来自列B的非空值相关联,因此当没有非空值显示时仅在B中显示空值。
大致为:

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))