2017-03-04 23 views
0

考慮下面的圖像參照不同的列在PostgreSQL中列

enter image description here

如果你想獲得一個包含所有步驟獲得非標記邊的長度的結果行,你可以做以下:

SELECT 
5 AS a, --side 1, triangle 1 
7 AS b, --side 2, triangle 1 
(5*5) AS a2, --a^2 
(7*7) AS b2, --b^2 
(5*5)+(7*7) AS c2, --a^2 * b^2 = c^2 
SQRT((5*5)+(7*7)) AS c, --√c2 = c 
19 AS d, --side 1, triangle 2 
24 AS e, --side 2 triangle 2 
(19*19) AS d2, --d^2 
(24*24) AS e2, --e^2 
(19*19)+(24*24) AS f2, --d^2 * e^2 = f^2 
SQRT((19*19)+(24*24)) AS f, --√f2 = f 
(5*5)+(7*7)+(19*19)+(24*24) AS g2, --c^2 * f^2 = g^2 
SQRT((5*5)+(7*7)+(19*19)+(24*24)) AS g --√g2 = g 

但是,這是非常醜陋的。我想使用列替換,如:

SELECT 
5 AS a, --side 1, triangle 1 
7 AS b, --side 2, triangle 1 
(a*a) AS a2, --a^2 
(b*b) AS b2, --b^2 
a2+b2 AS c2, --a^2 * b^2 = c^2 
SQRT(c2) AS c, --√c2 = c 
19 AS d, --side 1, triangle 2 
24 AS e, --side 2 triangle 2 
(d*d) AS d2, --d^2 
(e*e) AS e2, --e^2 
d+e AS f2, --d^2 * e^2 = f^2 
SQRT(f2) AS f, --√f2 = f 
c2+f2 AS g2, --c^2 * f^2 = g^2 
SQRT(g2) AS g --√g2 = g 

有沒有簡單的方法來做到這一點?

PS請不要解釋這是如何使用SQL的一個荒謬的,我知道這!這只是我能減少我的問題而被理解的最簡單的方法。在我的場景中,使用來自許多連接表的變量進行更復雜的計算,結果需要插入具有非常嚴格結構的彙總表中。目前,我將結果帶到Node進行計算並插入數據,但這非常慢,特別是因爲我要通過網絡訪問數據庫服務器。

回答

0

這可以使用公用表表達式來完成:

with base_vars (a,b,d,e) as (
    values (5),(7),(19),(24) 
), var2 (a2, b2, d2, e2) as (
    select a*a, b*b, d*d*, e*e 
    from base_vars, 
), var3 (c2, c, f2, f) as (
    select a2+b2, SQRT(a2+b2), d+e, sqrt(d+e) 
    from var2, base_vars 
), var3 (g2, g) as (
    select c2+f2, sqrt(c2+f2) 
    from var3 
) 
select sqrt(g) 
from var3; 

我不是100%,如果我得到了所有變量的權利,但我覺得你的想法。

另一種選擇是將它放到PL/pgSQL函數中。

+0

我打算測試一下,看看它是否適用於我的複雜用例。如果是這樣,我會接受,如果沒有,我會跟進問題。謝謝! – trex005

+0

@ trex005:簡化您的問題,使得簡化問題的答案不適用於您的實際問題通常不是一個好主意。我可能把這個計算放到一個PL/pgSQL函數中,你只需要通過4個輸入變量 –

+0

我當然明白,然而,提問者可能並不總是理解回答者要去的方向,因此可能不會預料到不兼容性直到他們看到了答案。 就我而言,問題在於我的連接和計算有多複雜,但是我通過將每個表達式堆疊得更像這樣簡化了方法:http://pastebin.com/7ZUbJVBG 它看起來可能更復雜,但在數百行的查詢中更容易跟蹤。 – trex005

0

lateral比CTE稍微短一點,因爲不需要參考之前的CTE。規劃人員不能將CTE和主要查詢合併到一個計劃中。

with t (a,b,d,e) as (values (5,7,19,24)) 
select c, f, sqrt(c2 + f * f) 
from 
    t 
    cross join lateral 
    (select a * a, b * b, d * d, e * e) t1 (a2, b2, d2, e2) 
    cross join lateral 
    (select a2 + b2, d2 + e2) t2 (c2, f2) 
    cross join lateral 
    (select sqrt(c2), sqrt(f2)) t3 (c, f) 
; 
     c   |  f   |  sqrt  
------------------+------------------+------------------ 
8.60232526704263 | 30.6104557300279 | 31.7962261911693