2013-11-04 95 views
2

我需要的是加入牌桌與基於其他表值第一行中的查詢:LEFT JOIN DB2 iSeries的與第一排

SELECT * FROM TABLEA A LEFT JOIN 
    (SELECT * from TABLEB 
     WHERE FIELD1 <> '3' and FIELD2 = 'D' AND A.CODE=CODE 
     FETCH FIRST 1 ROW ONLY 
    ) B 
on a.FIELDA = b.FIELDA 
and A.FIELDB = B.FIELDB 

但DB2返回錯誤,因爲不能使用A.CODE ...

如何解決這個問題?

+0

您在派生表中引用了tablea(別名爲A),但您沒有在from子句中使用它。我認爲你需要將它移到你的連接條款中。 – Andrew

+0

你能給我一個代碼嗎? –

+0

[在一個語句中選擇兩個表的連接中的第一行]的可能重複(http://stackoverflow.com/questions/774769/select-the-first-row-in-a-join-of-two-表一對一的聲明) – bluish

回答

4

您需要使用嵌套表表達式

SELECT * FROM TABLEA A LEFT JOIN 
    LATERAL (SELECT * from TABLEB 
    WHERE FIELD1 <> '3' and FIELD2 = 'D' AND A.CODE=CODE 
    FETCH FIRST 1 ROW ONLY 
) B 
on a.FIELDA = b.FIELDA 
and A.FIELDB = B.FIELDB 
+1

誰投了下來,關心解釋你的推理? – mustaccio

+0

我可能倒了投票我不記得了。降低投票成本的聲譽,所以不用擔心。哪裏存在就可以輕鬆執行第1行唯一語句。 – danny117

+0

公平地說'where exists'與問題中的查詢不同或相當,因爲它只返回TABLEA而不是TABLEB的列。 –

1

這是一種高度優化的語句。 您沒有從tableb獲取任何數據,並且您的第一行只有存在條件。

select a.* from tablea a 
where exists (select * from tableb b 
    where a.fielda = b.fielda 
    and a.fieldb = b.fieldb 
    and b.code = a.code 
    and b.field2 = 'd' and b.field1 <> '3') 
+0

但是,由於代碼中提到'SELECT *',我們不知道Daniele可能使用TableB – WarrenT

+0

@WarrentT這是真的。我想到了這一點,幾乎改變了我的答案。但是,如果僅選擇第一行而沒有order by子句,則不知道實際返回的行只有幾個字段才匹配。不知道更多的親密細節,我去了哪裏存在,因爲我經常這樣做給我學生至少有一種課程類型的查詢。 – danny117

0

可以使用OLAP功能row_number()根據(FIELDA,fieldb,代碼)組中somefield(S)排名記錄。例如,某個字段可能是事務ID或序列。 order by子句在此處是可選的,但如果沒有它,您可能會隨機選擇哪個記錄是組中的第一個記錄。

WITH B AS 
(SELECT *, 
     row_number() over (partition by fielda,fieldb,code 
          order  by somefield 
          ) as pick 
    from TABLEB 
    WHERE FIELD1 <> '3' 
     and FIELD2 = 'D' 
) 
SELECT * 
    FROM TABLEA A LEFT JOIN B 

     on a.FIELDA = b.FIELDA 
     and A.FIELDB = B.FIELDB 
     and A.CODE = B.CODE 
    where pick=1