在Postgres中的行到列a.k.a枢轴

时间:2014-09-23 09:39:06

标签: sql postgresql pivot case case-when

以下是我的选择查询

SELECT 
gtab12.AcName,  g9.TrNo::int, g9.TrDate,NetAmt,case when g9.vrid=42 then 'brin' else 'brout' end as voucher
FROM gtab09  g9
         INNER JOIN gtab10 using(TranId) 
         INNER JOIN gtab05 ON gtab10.BatchId = gtab05.BatchId 
         INNER JOIN gtab04 on gtab05.ProductId= gtab04.ProductId
         INNER JOIN gtab12 using(AcID) 
         INNER JOIN gtab07 on gtab04.PatentId= gtab07.PatentId  
WHERE    g9.BranchID = 2 
    And   g9.Vrid IN(42,43) 
    And acyrid = 2 
    AND trdate BETWEEN '2014-04-01' AND '2014-09-23' group by acname ,trno,trdate,netamt,vrid order by acname,voucher

这将返回如下所示的结果


如何将上述结果转换为(需要根据voucher 列将行转换为列

acname         | brin_trno | brin_trdate | brin_netamt | brout_trno | brout_trdate | brout_netamt
---------------+-----------+------------+--------------+------------+--------------+-------------
KREMCOS KOLLAM |         1 |2014-04-01 |   $51,610.00  |   null     |     null     |  null               
-------------------------------------------------------------------------------------------------
KREMCOS KOLLAM |        7  |2014-04-19 |   $95,543.00  |   null     |     null     |  null               
-------------------------------------------------------------------------------------------------
KREMCOS KOLLAM |      null |null       |null           |          10|2014-05-06    |$49,894.00
-------------------------------------------------------------------------------------------------
KREMCOS KOLLAM |     null  |null       |null           |          29| 2014-08-16   |$27,894.00
-------------------------------------------------------------------------------------------------
KREMCOS KOLLAM |     null  |null       |null           |         8  |2014-04-29     |$50,894.00

2 个答案:

答案 0 :(得分:0)

你真的不需要这个角色......你可以用这样的联盟做到这一点:

SELECT 
  gtab12.AcName,  
  g9.TrNo::int as brin_TrNo, 
  g9.TrDate as brin_TrDate,
  NetAmt as brin_NetAmt,
  NULL as brout_TrNo,
  NULL as brout_TrDate,
  NULL as brout_NetAmt
FROM gtab09  g9
         INNER JOIN gtab10 using(TranId) 
         INNER JOIN gtab05 ON gtab10.BatchId = gtab05.BatchId 
         INNER JOIN gtab04 on gtab05.ProductId= gtab04.ProductId
         INNER JOIN gtab12 using(AcID) 
         INNER JOIN gtab07 on gtab04.PatentId= gtab07.PatentId  
WHERE    g9.BranchID = 2 
    And   g9.Vrid = 42 
    And acyrid = 2 
    AND trdate BETWEEN '2014-04-01' AND '2014-09-23' 
GROUP BY acname ,trno,trdate,netamt,vrid 
UNION    
SELECT 
  gtab12.AcName,  
  NULL as brin_TrNo, 
  NULL as brin_TrDate,
  NULL as brin_NetAmt,
  g9.TrNo::int  as brout_TrNo,
  g9.TrDate as brout_TrDate,
  NetAmt as brout_NetAmt
FROM gtab09  g9
         INNER JOIN gtab10 using(TranId) 
         INNER JOIN gtab05 ON gtab10.BatchId = gtab05.BatchId 
         INNER JOIN gtab04 on gtab05.ProductId= gtab04.ProductId
         INNER JOIN gtab12 using(AcID) 
         INNER JOIN gtab07 on gtab04.PatentId= gtab07.PatentId  
WHERE    g9.BranchID = 2 
    And   g9.Vrid = 42 
    And acyrid = 2 
    AND trdate BETWEEN '2014-04-01' AND '2014-09-23' 
GROUP BY acname ,trno,trdate,netamt,vrid 

答案 1 :(得分:0)

您无需使用crosstab进行此选择,您可以使用CASE-WHEN进行锻炼

SELECT t.acname , 
         CASE WHEN t.voucher='brin'  THEN t.trno    END AS brin_trno,
         CASE WHEN t.voucher='brin'  THEN t.trdate  END AS  brin_trdate,
         CASE WHEN t.voucher='brin'  THEN t.netamt  END AS brin_netamt,
         CASE WHEN t.voucher='brout' THEN t.trno    END AS brout_trno,
         CASE WHEN t.voucher='brout' THEN t.trdate  END AS brout_trdate,
         CASE WHEN t.voucher='brout' THEN t.netamt  END AS brout_netamt
FROM
        (
SELECT 
gtab12.AcName,  g9.TrNo::int, g9.TrDate,NetAmt,case when g9.vrid=42 then 'brin' else 'brout' end as voucher
FROM gtab09  g9
         INNER JOIN gtab10 using(TranId) 
         INNER JOIN gtab05 ON gtab10.BatchId = gtab05.BatchId 
         INNER JOIN gtab04 on gtab05.ProductId= gtab04.ProductId
         INNER JOIN gtab12 using(AcID) 
         INNER JOIN gtab07 on gtab04.PatentId= gtab07.PatentId  
WHERE    g9.BranchID = 2 
    And   g9.Vrid IN(42,43) 
    And acyrid = 2 
    AND trdate BETWEEN '2014-04-01' AND '2014-09-23' group by acname ,trno,trdate,netamt,vrid order by acname,voucher
        ) t