2011-04-09 74 views

回答

8

您可以通過將表格與自身結合(執行所謂的笛卡爾或cross join)來完成此操作。看下面的例子。

SELECT a.name, a.gdppc, SUM(b.gdppc) 
FROM gdppc AS a, gdppc AS b WHERE b.gdppc <= a.gdppc 
GROUP BY b.id ORDER BY a.gdppc; 

給定一個包含國家及其人均國內生產總值的表,它會給你一個GDP數字的運行總數。

Democratic Republic of Congo|329.645|329.645 
Zimbabwe|370.465|700.11 
Liberia|385.417|1085.527 
Burundi|399.657|1485.184 
Eritrea|678.954|2164.138 
Niger|711.877|2876.015 
Central African Republic|743.945|3619.96 
Sierra Leone|781.594|4401.554 
Togo|833.803|5235.357 
Malawi|867.063|6102.42 
Mozambique|932.511|7034.931 
... 

注意,這可能是一個非常耗費資源的操作,因爲如果一個表有N個元素,將創建N * N個元素的臨時表。我不會在一張大桌子上表演。

+0

謝謝。在你的例子中,什麼是TABLE名字? – Hugo 2011-04-09 18:01:24

+0

@Diomidis Spinellis:實際上它不是交叉連接,而是[三角形連接](http://www.sqlservercentral.com/articles/T-SQL/61539/)。 – 2011-04-09 18:50:56

+0

我很抱歉,但我沒聽懂。在FROM語句中,我應該在哪裏寫我的TABLE名稱? – Hugo 2011-04-09 19:36:18

-1

你必須做一個總和在您需要的領域....查詢取決於你正在使用的數據庫,Oracle允許你這樣做:

select id, value, sum(value) as partial_sum over (order by id) from table 
1

Diomidis Spinellis交叉連接解決方​​案的建議已經花了O(N^2)次。如果你可以忍受這些令人費解的代碼,遞歸CTE可以更快地工作。

這產生與他相同的輸出。

WITH RECURSIVE running(id, name, gdppc, rt) AS (
    SELECT row1._rowid_, row1.name, row1.gdppc, COALESCE(row1.gdppc,0) 
    FROM gdppc AS row1 
    WHERE row1._rowid_ = (
     SELECT a._rowid_ 
     FROM gdppc AS a 
     ORDER BY a.gdppc, a.name, a._rowid_ 
     LIMIT 1) 
    UNION ALL 
    SELECT row_n._rowid_, row_n.name, row_n.gdppc, COALESCE(row_n.gdppc,0)+running.rt 
    FROM gdppc AS row_n INNER JOIN running 
    ON row_n._rowid_ = (
     SELECT a._rowid_ 
     FROM gdppc AS a 
     WHERE (a.gdppc, a.name, a._rowid_) > (running.gdppc, running.name, running.id) 
     ORDER BY a.gdppc, a.name, a._rowid_ 
     LIMIT 1)) 
SELECT running.name, running.gdppc, running.rt 
FROM running; 

排序和比較照顧重複的,COALESCE有沒有忽略空值。

如果你有一個好的索引,這應該是O(N log N)。由於SQLite不支持遊標,如果不依賴外部應用程序,O(N)解決方案可能不存在。