更快的联合表SQL方式

时间:2017-11-10 20:59:19

标签: sql postgresql

我有TABLE_A

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 个答案:

答案 0 :(得分: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条件产生true,则CASE表达式的值是ELSE子句的结果。 如果省略ELSE子句且没有条件为真,则结果为null

括号也可以省略:

因此,查询可以在语法上简化为:

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

......稍微更具可读性。

答案 1 :(得分: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