2009-05-28 152 views
12

我一直忍受着一些SQL,其中有幾行數據,並且我想從上一行中減去一行並將其重複一遍。在SQL中從另一行中減去一行數據

因此,這裏的表:

CREATE TABLE foo (
    id, 
    length 
)
INSERT INTO foo (id,length) VALUES(1,1090) 
INSERT INTO foo (id,length) VALUES(2,888) 
INSERT INTO foo (id,length) VALUES(3,545) 
INSERT INTO foo (id,length) VALUES(4,434) 
INSERT INTO foo (id,length) VALUES(5,45)

我想要的結果顯示第三列叫做差異這是一排從下方最後一行從零減去一個減去。

 
+------+------------------------+ 
| id |length | difference | 
+------+------------------------+ 
| 1 | 1090 | 202   | 
| 2 | 888 | 343   | 
| 3 | 545 | 111   | 
| 4 | 434 | 389   | 
| 5 | 45 | 45   |

我已經嘗試了自我加入,但我不完全確定如何限制結果,而不是讓它自行循環。我不能確定id值對於給定的結果集是連續的,所以我沒有使用該值。我可以擴展模式以包含某種順序值。

這是我已經試過:

SELECT id, f.length, f2.length, (f.length - f2.length) AS difference 
FROM foo f, foo f2

謝謝你的幫助。

+0

這是MySQL。原諒我以前不提。 – 2009-05-28 04:32:27

回答

13

這可能會幫助你(有點)。

 

select a.id, a.length, 
coalesce(a.length - 
    (select b.length from foo b where b.id = a.id + 1), a.length) as diff 
from foo a 
 
+0

+1你打我吧shahkalpesh – northpole 2009-05-28 04:16:21

+0

使用COALESCE將修復最後一行有NULL – shahkalpesh 2009-05-28 04:18:44

+0

他希望從最後一行減去零,所以差異列應該有45,但你的腳本給0 0 – TheVillageIdiot 2009-05-28 04:20:08

1

什麼是這樣的:

SELECT T2.ID, T2.[Length], T2.[Length]-T1.[Length] AS 'Difference' 
FROM Foo AS T1 RIGHT OUTER JOIN Foo AS T2 ON (T1.ID = (T2.ID-1)) 
ORDER BY T1.ID 
1

編輯:固定在重讀Q(誤解)

SELECT f.id, 
     f2.id, 
     f.length, 
     f2.length, 
     (f.length -f2.length) AS difference 
FROM foo f, 
    foo f2 
where f2.id = f.id+1 

ID是曖昧

編輯:注:測試in mysql 5.0

6

Yi撒尿!!!這樣做的伎倆:

SELECT f.id, f.length, 
    (f.length - ISNULL(f2.length,0)) AS diff 
FROM foo f 
LEFT OUTER JOIN foo f2 
ON f2.id = (f.id +1) 

請檢查是否有其他案件也,它正在爲您發佈的值! 請注意這是針對SQL Server 2005的

2

所以他們只是從最大到最小的順序?

SELECT f.id, f.length, (f.length - ISNULL(t.length, 0)) AS difference 
FROM foo AS f 
LEFT JOIN (
    SELECT f1.id 
     ,MAX(f2.length) as length 
    FROM foo AS f1 
    INNER JOIN foo AS f2 
     ON f1.length > f2.length 
    GROUP BY f1.id 
) AS t -- this is the triangle 
    ON t.id = f.id 

可以使用COALESCE(或IFNULL),而不是ISNULL爲MySQL。

1
Select f1.id, f1.seqnum, f2.seqnum, f1.length, f2.length, f1.length-f2.length 

From (

Select Id, length, row_number(order by length) 'seqnum' 
From 
foo 

) f1 

Inner join (

Select 
Id, length, row_number(order by length) 'seqnum' from foo union select 0, 0, 0 

) f2 

On f1.seqnum = f2.seqnum + 1 

Order by f1.length desc 
0

我有這個問題,看看你的解決方案很有趣。 我發現奇怪的是,這樣的正常生活問題在SQL中非常複雜。 因爲我只需要報告中的值,所以我選擇了完全不同的解決方案。 我正在運行Ruby on Rails作爲我的sqlite3數據庫的前端,只是在視圖中做了這樣的減法:

在你的ruby控制器中,有一個對象變量@foo,它包含由您的查詢。

在視圖中,只是做

<table border=1> 
    <tr> 
    <th>id</th> 
    <th>length</th> 
    <th>difference</th> 
    </tr> 

<% for i in [email protected] do %> 
    <tr> 
    <td><%=h @foo[i].id %></td> 
    <td><%=h @foo[i].length %></td> 
    <td><% if ([email protected]) then %> 
     <%= @foo[i].length %> 
     <% else %> 
     <%= @foo[i+1].length.to_i - @foo[i].length.to_i %> 
     <% end %> 
    </td> 
    </tr> 
<% end %> 
</table> 

似乎是比SQL解決方案更健壯。

相關問題