2011-10-25 71 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))