2013-01-10 29 views
0

讓我試着解釋一下這個場景。我有兩個表A(列 - A1,A2,A3)& B(列-B1,B2,B3)。我需要將表A連接到A1.B2上的表B.對於每個連接,表B有一個或兩個記錄,其中B3(X或Y)的值不同。我想寫一個查詢,JOIN查詢需要選擇B3 = X的行(如果沒有其他行,B3 = Y);如果存在兩行(B3 = X & B3 = Y),則查詢只需選取B3 = Y的行(忽略B3 = X的行)。ORACLE Special JOIN

讓我試着給一些數值表&解釋一點點。

 
Table A 
******** 
A1 A2 A3 
1 11 111 
2 22 222 
3 33 333 
4 44 444 

Table B 
******** 
B1 B2 B3 
6 1 X 
7 1 Y 
8 2 X 
9 3 X 
10 3 Y 
11 4 X 

Again.. JOIN is on A1.B2. The result should be as following, 

JOIN Results 
************* 
A1 A2 A3 B1 B2 B3 
1 11 111 7 1 Y 
2 22 222 8 2 X 
3 33 333 10 3 Y 
4 44 444 11 4 X 

讓我知道你們是否對我的問題有任何澄清。

在此先感謝。 瑜珈

+0

爲X和Y的實際值?如果不是,這些值是否可比? –

+0

B1是表B的主鍵 –

+0

表「B」是否有其他列? –

回答

3

你可以選擇從表B中的行與ROW_NUMBER功能,如果你通過連接列和秩序由你「選取順序劃分「列:

SELECT b1, b2, b3, 
     ROW_NUMBER() OVER (PARTITION BY b2 ORDER BY b3 DESC) as rn 
    FROM b; 

1 Y 1 
1 X 2 
2 X 1 
3 Y 1 
3 X 2 
4 X 1 

然後你就可以過濾第一排,一個與rn=1

然後個

過濾後的行可以加入到表:

SELECT * 
    FROM a 
    JOIN (
     SELECT b1, b2, b3 
      FROM (SELECT b1, b2, b3, 
         ROW_NUMBER() OVER (PARTITION BY b2 ORDER BY b3 DESC) as rn 
        FROM b 
       ) 
      WHERE rn=1 
     ) bfilter ON a.a1 = bfilter.b2; 

1 11 111 7 1 Y 
2 22 222 8 2 X 
3 33 333 10 3 Y 
4 44 444 11 4 X 

如果「X」和「Y」不是實際值,你可以用一個CASE聲明延長ORDER子句允許一般值:

ROW_NUMBER() OVER (PARTITION BY b2 ORDER BY 
    CASE b3 WHEN 'Y' THEN 1 
      WHEN 'X' THEN 2 
      ... 
    END ASC) 

編輯:

SELECT a1, a2, a3, b1, b2, b3 
    FROM (
     SELECT a1, a2, a3, b1, b2, b3, 
       ROWNUMBER() OVER (PARTITION BY a1 ORDER BY 
        CASE WHEN a2=... AND b3=... THEN 1 
         WHEN a2=... AND b3=... THEN 2 
         ... 
        END ASC) 
      FROM a JOIN b ON a.a1 = b.b2 
     ) 
    WHERE rn = 1; 
+0

不錯。很好的解釋。我還有一個子問題。有什麼辦法可以把另一個條件表A.在相同的條件下,如果表B有兩個記錄和表A中的一個字段(A3)有一個特定的值(比如0),我想要做同樣的事情(選擇記錄B與'Y')。 – Yogi

+0

當然,您只需更改訂單,首先加入,然後訂購。我會編輯答案... –

+0

讓我改述一下。目前,如果表B有兩條記錄(B3的值爲X和Y),我們用Y選擇一條記錄。現在,我需要再添加一個條件,在相同的條件下(表B有兩條X&Y記錄),如果A3 = 0,我需要選擇B3 = X的行(而不是B3 = Y的行)。請讓我知道,如果它是一個可以做的事情。謝謝@Wolfgang – Yogi

0

這裏的,我會怎麼做:

  • 使由B2
  • 取最大值(B3)

聯接

  • 組這樣可以確保僅在沒有按字母順序排列的較高值(Y)時才選取X.

  • +0

    我沒有分組就需要它。不管怎麼說,還是要謝謝你。 – Yogi

    0

    隨着UNION

    select a.*,b.* from a,b 
    where a.a1=b.b2 
    and b.b3='Y' 
    union 
    select a.*,b.* from a,b 
    where a.a1=b.b2 
    and not exists (select bb.br from b bb where bb.b2=a.a1 and bb.b3='Y') 
    

    沒有UNION

    select a.*,b.* from a,b 
    where a.a1=b.b2 
    and (b.b3='Y' 
    or not exists (select bb.b3 from b bb where bb.b2=a.a1 and bb.b3='Y')) 
    

    這裏的約束是B有確切1或2行各設置的行