我在我們的postgres db(版本8.4.22)上試過這個,因爲小提琴對我的口味有點慢。但SQL可以粘貼在那裏,它適用於postgres。
這裏仍然是fiddle demo第一次需要20秒,但後來更快。
下面是爲我生成計算結果的原因。 (我沒有按照您的要求格式化,因爲在我的腦海裏的主要是鍛鍊; Tibial計算)。這是假設你的表稱爲activity
:
with recursive rekmatriks as(
select id, activity, pay, parent, id::text as matriks, 0 as lev
from activity
where parent is null
union all
select activity.id, activity.activity, activity.pay, activity.parent,
rekmatriks.matriks || '-' || activity.id::text as matriks,
rekmatriks.lev+1 as lev
from activity inner join rekmatriks on activity.parent = rekmatriks.id
)
, reksum as (
select id, activity, pay, parent, matriks, lev, coalesce(pay,0) as subsum
from rekmatriks
where not exists(select id from rekmatriks rmi where rmi.parent=rekmatriks.id)
union all
select rekmatriks.*, reksum.subsum+coalesce(rekmatriks.pay, 0) as subsum
from rekmatriks inner join reksum on rekmatriks.id = reksum.parent)
select id, activity, pay, parent, matriks, sum(subsum) as amount, lev
from reksum
group by id, activity, pay, parent, matriks, lev
order by id
作爲獎勵,這帶來的嵌套深度ID。 0代表父母,1代表第一個子代等。這使用兩個遞歸WITH queries來實現你想要的。您需要的計算值位於amount
列中。
第一個(rekmatriks
)處理表中從頂部到底部的ID,從具有父項NULL
的任何ID開始。遞歸部分簡單地獲取父id,並將它自己的id添加到它,以實現您的matriks樹表示字段。
第二個(reksum
)從下到上工作,並從沒有子元素的所有行開始。此查詢的遞歸部分爲非遞歸部分中選定的每個子行選擇一個父行,並計算每行的pay
和subsum
的總和。這會爲每個ID生成多行,因爲一個父級可以有多個子級。
現在剩下的就是最終的選擇聲明。它使用GROUP BY
和SUM
將多個可能的子和值整合到一行中。
這對您的特定示例有效。如果樣本數據中沒有顯示不同的情況,則可能會失敗,例如,如果具有子女的項目帶有需要添加的值。
當你說表時,你的意思是db或php?如果db你使用的是什麼RDBMS?那些'{}'是什麼? –
什麼是matriks?你的邏輯是什麼? – Ravi
@jWeaver在支付飲用水'1-3-6'的情況下,我認爲是因爲增加了行'1,3和6' - '付全部,付水,付飲料' –