2009-04-21 58 views
9

我只需要選擇連接表A和B的查詢中的第一行。在表B上存在多個具有相同名稱的記錄。這兩個表格中沒有任何標識符。我無法改變計劃,因爲我沒有擁有數據庫。在一個語句中選擇兩個表的連接中的第一行

TABLE A 
NAME 

TABLE B 
NAME 
DATA1 
DATA2 

Select Distinct A.NAME,B.DATA1,B.DATA2 
From A 
Inner Join B on A.NAME = B.NAME 

這給了我

NAME  DATA1 DATA2 
sameName 1  2 
sameName 1  3 
otherName 5  7 
otherName 8  9 

,但我需要檢索每名只有一排

NAME  DATA1 DATA2 
sameName 1  2 
otherName 5  7 

我能夠通過添加結果到一個臨時表與要做到這一點標識列,然後選擇每個名稱的最小標識。

這裏的問題是,我需要在一個單一的陳述中這樣做。

回答

0

不知道這是否能解決您的問題,但您可以嘗試使用GROUP BY子句並按名稱列之一進行分組。

DB2 Group by tutorial

7

使用GROUP BY可能讓你中途有,但要小心。如果你做這樣的事情:

Select A.NAME, min(B.DATA1), min(B.DATA2) 
From A Inner Join B on A.NAME = B.NAME 
Group by A.NAME; 

你會得到你正在尋找的結果:

NAME  DATA1 DATA2 
    sameName 1  2  
    otherName 5  7 

但只有您使用測試數據的原因。如果更改數據,從而代替:

otherName 8  9 

你有:

otherName 8  4 

這將返回:

NAME  DATA1 DATA2 
    sameName 1  2  
    otherName 5  4 

需要注意的是中文別名不從返回DATA1和DATA2相同的記錄!

更新:對數據值的一個比較自聯接可以幫助你,比如:

SELECT a.*, b.* FROM a,b 
    LEFT JOIN b b2 ON b.name = b2.name AND b.data2 < b2.data2 
    WHERE a.name = b.name AND b2.data2 IS NOT NULL; 

但是,這隻有在DATA2值是每個名稱唯一工作。

+0

上一條語句有小錯字。它應該是「IS NOT NULL」而不是「IN NOT NULL」。 – mbp 2010-03-17 20:27:32

+0

+1你是一個救世主。由於SQL CE的限制,即使使用SQL CE,您編輯的自連接也可以工作,因爲此問題的其他解決方案並不適用。 – 2012-04-27 06:43:48

0

如果您可以添加到臨時表然後從中進行查詢,則可以一次完成。

WITH T AS (temp table select), RN AS (select min row-numbers from T) SELECT T.NAME, T.DATA1, T.DATA2 FROM T INNER JOIN RN on T.row_number = RN.row_number 

有很多其他的方式來寫這個,但這就是我一直在做類似的事情。

0

嘗試重複數據刪除b類似這樣

SELECT A.NAME, bb.DATA1, bb.DATA2 
FROM A 
JOIN B bb 
ON  A.NAME = B.NAME 
WHERE NOT EXISTS (SELECT * 
        FROM B 
        WHERE NAME = bb.NAME 
          AND (DATA1 > bb.DATA1 
           OR DATA1 = bb.DATA1 AND DATA2 > bb.DATA2))

添加更多或條款是否存在更多的數據X列。

如果A也包含重複項,則只需在OP中使用DISTINCT即可。

10

這將工作:

with temp as (
    select A.NAME, B.DATA1, B.DATA2, 
     row_number() over (partition by A.NAME order by A.NAME) as rownum 
    from TABLEA A inner join TABLEB B 
    on A.NAME = B.NAME 
) 
select NAME, DATA1, DATA2 from temp where rownum = 1 

如果你想選擇數據1的最低值,並將其數據2中,然後利用這種變化:

with temp as (
    select A.NAME, B.DATA1, B.DATA2, 
     row_number() over (partition by A.NAME order by B.DATA1, B.DATA2) as rownum 
    from TABLEA A inner join TABLEB B 
    on A.NAME = B.NAME 
) 
select NAME, DATA1, DATA2 from temp where rownum = 1 

這兩個查詢會給每一個行名稱。

0
​​

這會給你想要的結果,提供B.DATA1值是與表A

如果他們不是唯一的集內獨特,我唯一知道的另一種方式是使用在MSSQL 2005及以上版本中交叉應用。

0

這個問題的標籤表明,這將是DB2的解決方案,但是這是非常相似的MS-SQL服務器,如果是這樣嘗試以下解決方案:

使用交叉,將有可能顯示什麼只存在於兩個表

select A.*, B.DATA1, B.DATA2 
from A 
cross apply (select top 1 * from B where B.name = A.name) B 

但它有可能改變到OUTER顯示在一個什麼不存在的義務在乙

select A.*, B.DATA1, B.DATA2 
from A 
OUTER apply (select top 1 * from B where B.name = A.name) B 

存在在structu因爲在表B中沒有關於退出順序的指示,所以也可能包含ORDER語句。

0

您可以使用行號爲每個名稱獲取一行,嘗試類似低於

Select name,data1,data2 from 
(Select A.NAME,B.DATA1,B.DATA2,row_number() over(partitioj by a.name order by a.name) rn 
From A 
Inner Join B on A.NAME = B.NAME) where rn=1 
相關問題