2017-08-23 34 views
2

我通過Npgsql驅動程序爲Windows/NET使用PostgreSQL,我發現通過它可以使用PL/pgSQL語言。
所以這樣我可以利用的變量我的計算腳本,可能看起來就像這個例子:PostgreSQL,變量

DO $$ 
DECLARE 
    tlist text='mylistofbills'; 
    tcontent text='mycontentofbills'; 

BEGIN 
CREATE TEMP TABLE tlist 
     (billno integer, bdate timestamp, rebate double precision) 
     ON COMMIT DROP; 

INSERT INTO tlist 
VALUES (1, '10.01.2017. 10:14:56', 10), 
     (2, '10.01.2017. 11:02:13', 5), 
     (3, '10.01.2017. 11:45:22', 0), 
     (4, '10.01.2017. 12:01:01', 6); 

CREATE TEMP TABLE tcontent 
     (billno integer, rowno integer, price double precision, tax double precision) 
     ON COMMIT DROP; 

INSERT INTO tcontent 
VALUES (1, 1, 100, 19), 
     (1, 2, 30, 0), 
     (2, 1, 20, 19), 
     (3, 1, 18, 19), 
     (4, 1, 43, 0); 
END $$; 

SELECT s.price, 
     l.rebate, 
     s.price/100*l.rebate AS valrebate, 
     s.price-(s.price/100*l.rebate) AS worebate, 
     ((s.price-(s.price/100*l.rebate))/100)*s.tax AS valtax, 
     s.price-(s.price/100*l.rebate)+(((s.price-(s.price/100*l.rebate))/100)*s.tax) AS finalprice 
    FROM tlist l, tcontent s 
WHERE l.billno=s.billno; 

實施方式是(從實際情況)簡化,適用於粘貼到的pgAdmin的SQL編輯器。
所以,現在是問題:我可以以某種方式在這些代碼的主體,而不添加新的功能,以服務器使用公式編寫更優雅和可讀的代碼?
如果我將能夠添加簡單的公式,如:

rebatec=s.price/100*l.rebate 
priceworebate=s.price-rebatec 

然後我的代碼看起來更易讀且不易出錯。
像這樣:

SELECT s.price, 
     l.rebate, 
     rebatec AS valrebate, 
     priceworebate AS worebate, 
     (priceworebate/100)*s.tax AS valtax, 
     priceworebate+((priceworebate/100)*s.tax) AS finalprice 
    FROM tlist l, tcontent s 
WHERE l.billno=s.billno; 

如果有可能在哪裏以及如何把這個公式,以便它可以在我的最後一個SELECT代碼中使用?

SOLUTION: 基於@ Clodo阿爾的答案,給新的東西給我,我覺得這我能理解一個解決方案:

SELECT s.price, 
     l.rebate, 
     rebatec AS valrebate, 
     priceworebate AS worebate, 
     priceworebate/100*s.tax AS valtax, 
     priceworebate+priceworebate/100*s.tax AS finalprice 
    FROM tlist l, tcontent s, LATERAL 
     (SELECT s.price/100*l.rebate AS rebatec, 
       s.price-s.price/100* l.rebate AS priceworebate 
     )sub 
WHERE l.billno=s.billno; 

它的工作,我希望這是技術上是正確的。

回答

2

使用lateral

側向關鍵字可以先一個子SELECT SELECT項目。這允許子SELECT在FROM列表中引用出現在它之前的FROM項目的列。

select 
    s.price, 
    l.rebate, 
    rebatec as valrebate, 
    priceworebate as worebate, 
    priceworebate/100 * s.tax as valtax, 
    priceworebate + priceworebate/100 * s.tax as finalprice 
from 
    tlist l 
    inner join 
    tcontent s using (billno) 
    cross join lateral (
     select 
      s.price/100 * l.rebate as rebatec, 
      s.price - s.price/100 * l.rebate as priceworebate 
    ) cjl 

使用現代化的連接語法。

+0

WOW,從來沒有聽說過!順便說一句,它的作品,除了你在上次選擇時錯過了一個逗號。 –

+0

@WineToo:確定。 –

+0

請參閱我編輯的問題,結束它。 –

2

你可以使用子查詢來定義這些變量:

select var1 * col3 
from (
     select col1/col2 as var1 
     ,  * 
     from YourTable 
     ) sub 

或可替代的公共表表達式:

with cte as 
     (
     select col1/col2 as var1 
     ,  * 
     from YourTable 
     ) 
select var1 * col3 
from cte 
+0

謝謝。你認爲表現如何?子查詢還是cte? –