2013-06-05 51 views
1

我需要幫助構建一個查詢,該查詢返回值+來自同一表的另一個值與給出結果的另一個值之間的最小差異(加上總和不能是本身的價值)選擇T-SQL中兩列總結的最小差異

表的總和:

ID Value 
1  1   
2  2   
3  5   
4  -10  
5  -5 
6  3 
7  -15 

預期結果:

ID Value MinDif IDofTheOtherValue 
1  1  3  2     <-- MinDif = 1 + 2 (ID 1 + ID 2) 
2  2  3  1     <-- MinDif = 2 + 1 (ID 2 + ID 1) 
3  5  0  5     <-- MinDif = 5 + -5 (ID 3 + ID 5) 
4  -10  -5  3     <-- MinDif = -10 + 5 (ID 4 + ID 3) 
5  -5  0  3     <-- MinDif = -5 + 5 (ID 5 + ID 3) 
6  3  -2  5     <-- MinDif = 3 + -5 (ID 6 + ID 5) 
7  -15  -10  3     <-- MinDif = -15 + 5 (ID 7 + ID 3) 

這裏有一個查詢來創建表:

DECLARE @myTable TABLE(ID int, Value int) 
INSERT INTO @myTable VALUES (1, 1), (2,2), (3, 5), (4, -10), (5, -5), (6, 3), (7, -15) 

這裏就是我已經盡力了,但是這給SQL錯誤(不能對包含聚合或子查詢的表達式執行聚合函數。)

SELECT m.ID, MIN(ABS(m.Value + (SELECT m2.Value FROM @myTable m2))) 
FROM @myTable m 
+0

你認爲表上的JOIN語句嗎? – simsim

+3

我無法按照您的預期結果.... – bummi

+0

我編輯了預期的結果,以澄清我想要得到的結果 – Jaska

回答

2

這是給你的要求的結果:

with diffRank as 
(
    select ID = t1.ID 
    , minDif = t1.value + t2.value 
    , IDofTheOtherValue = t2.ID 
    , diffRank = row_number() over (partition by t1.ID order by abs(t1.value + t2.value), t2.ID) 
    from @myTable t1 
    inner join @myTable t2 on t1.ID <> t2.ID 
) 
select ID 
    , minDif 
    , IDofTheOtherValue 
from diffRank 
where diffRank = 1 
order by ID; 

SQL Fiddle with demo

1

我自己解決了這個。這裏的選擇條款:

SELECT tab.ID, tab.Value, test.*  
FROM @myTable tab 
OUTER APPLY 
(SELECT TOP 1 ID AS [AnotherID], [SUM] 
    FROM 
    (
     SELECT m.ID, m2.ID AS [ID2], m.Value + m2.Value AS [SUM] 
     FROM @myTable m 
     JOIN @myTable m2 ON m2.ID <> m.ID  
    ) apu WHERE ID2 = tab.ID ORDER BY ABS([SUM])) test 
0

在Oracle中,我會做:

select x.id, (select min(abs(x.value + y.value)) from my_table y), 
     (select first value (y.id) over (order by abs(x.value + y.value)) 
      from my_table y) 
from my_table x 

想起在TSQL

0

類似試試這個..它應該工作的東西。

DECLARE @myTable TABLE(ID int, Value int) 
INSERT INTO @myTable VALUES (1, 1), (2,2), (3, 5), (4, -10), (5, -5), (6, 3), (7, -15) 

SELECT C.ID, C.Value 
, C.Value + (SELECT TOP 1 E.Value FROM @myTable E WHERE C.AbsMinDif = ABS(C.Value + E.Value) ORDER BY E.ID) MinDif 
, (SELECT TOP 1 F.ID FROM @myTable F WHERE C.AbsMinDif = ABS(C.Value + F.Value) ORDER BY F.ID) IDofTheOtherValue 
FROM (

SELECT A.ID, MIN(A.Value) Value, MIN(ABS(A.Value + B.Value)) AbsMinDif 
FROM @myTable A 
CROSS JOIN @myTable B 
WHERE A.ID <> B.ID 
GROUP BY A.ID 

) C