2017-11-10 135 views
0

我TABLE_A更快地工會表SQL

mode   bank_id  amount 
'Outgoing' 1    100   
'Incoming' 1    200 
'Outgoing' 1    300 
'Incoming' 2    200 

我需要把它變成

from_bank_id   to_bank_id  amount 
1      null    100   
null     1     200 
1      null    300   
null     2     200 

現在我做這個

SELECT 
     amount, 
     NULL AS from_bank_id, 
     bank_id AS to_bank_id 
    FROM TABLE_A WHERE mode = 'Incoming' 
    UNION ALL 
    SELECT 
     amount, 
     NULL AS to_bank_id, 
     bank_id AS from_bank_id 
    FROM TABLE_A WHERE mode = 'Outgoing' 

這個SQL作品並給予我是我想要的輸出。只是伸出手去查看是否有更好的方法來實現這一點而不用查詢表格兩次?

這是第二部分的第一部分的查詢Reducing number of query for inner join when joining base on same table

+2

注意有使用'UNION'這本身沒有什麼錯,並且確實是一個'UNION ALL'會更快(在返回之前,而不是緩衝的結果)讓結果立即返回。 – Dai

回答

4
SELECT 
    (CASE WHEN mode = 'Outgoing' THEN bank_id ELSE NULL END) AS from_bank_id, 
    (CASE WHEN mode = 'Incoming' THEN bank_id ELSE NULL END) AS to_bank_id, 
    amount 
FROM 
    table_a 

PostgreSQL的CASE表達允許ELSE NULL與相同的行爲(重點煤礦)被省略:

https://www.postgresql.org/docs/current/static/functions-conditional.html
如果沒有WHEN條件成立時,CASE表達式的值是ELSE子句的結果。 如果省略ELSE子句並且沒有條件爲真,則結果爲空

括號也可以省略:

所以查詢可以被語法簡化爲:

SELECT 
    CASE WHEN mode = 'Outgoing' THEN bank_id END AS from_bank_id, 
    CASE WHEN mode = 'Incoming' THEN bank_id END AS to_bank_id, 
    amount 
FROM 
    table_a 

...這是稍微更具有可讀性。

+0

謝謝!不知何故,我知道我可以利用CASE。感謝您的澄清!另外,這是否比我正在做的更快?我想知道如何比較sql語句:)它只是簡單地運行了多少個查詢? – Zanko

+1

@Zanko如果某種方式比純粹來自代碼的方式更快,則無法確定。您需要自己對代碼進行基準測試/分析。它還取決於索引,數據在磁盤上的物理排列方式,DBMS緩存等等。您可以先查看執行計劃('EXPLAIN':https://www.postgresql.org/docs/9.3/static/sql-explain.html) – Dai

+0

也可以使用COALESCE以及 –

1

您可以使用CASE表達式更高效(並且容易)完成此操作。

select 
    case 
     when mode = 'Outgoing' then bank_id 
     else null 
    end as from_bank_id 
    ,case 
     when mode = 'Incoming' then bank_id 
     else null 
    end as to_bank_id 
    ,amount 
from 
    TABLE_A