2017-05-08 22 views
0

payment_infoという名前のテーブルがあり、以下のレコードがあります。postgresql - 単一行を複数の行に変更する

paymentid | customercode | previousbalance | paymentamount | remainingbalance 
----------------------------------------------------------------------------- 
PID0001 | CUST024 | 10000  |  2500  | 7500 
PID0002 | CUST031 | 8500   |  3500  | 5000 
PID0003 | CUST005 | 12000  |  1500  | 10500 

次に、上記の表の3行1行を作成します。 私の結果はこのように見えます。

Payment Group | Payment Line Item | Payment ID | Customer Code |  Type   | Amount  
-------------------------------------------------------------------------------------------------- 
    1   |   1   | PID0001 | CUST024  | PREVIOUS BALANCE | 10000.00  
    1   |   2   |   |    | PAYMENT AMOUNT  | 2500.00  
    1   |   3   |   |    | REMAINING BALANCE | 7500.00  

    2   |   1   | PID0002 | CUST031  | PREVIOUS BALANCE | 8500.00  
    2   |   2   |   |    | PAYMENT AMOUNT  | 3500.00  
    2   |   3   |   |    | REMAINING BALANCE | 5000.00  

    3   |   1   | PID0003 | CUST005  | PREVIOUS BALANCE | 12000.00  
    3   |   2   |   |    | PAYMENT AMOUNT  | 1500.00  
    3   |   3   |   |    | REMAINING BALANCE | 10500.00  

これは私が始めたクエリです。しかし、それは上記と同じ結果を返さなかった。

select row_number() over() as id,paymentid,customercode,'PREVIOUS BALANCE' as type,previousbalance from payment_info 
union 
select row_number() over() as id,'','','PAYMENT AMOUNT' as type,paymentamount from payment_info 
union 
select row_number() over() as id,'','','REMAINING BALANCE' as type,remainingbalance from payment_info 

UNIONキーワードを使用しない他の方法はありますか?実際のテーブルでは、30個以上のカラムを使用して何千ものレコードをクエリします。

また、支払いグループ(支払いIDごと)と支払いラインアイテム(グループごと)から自動生成番号(ID)を作成する方法もわかりません。

ありがとう

+0

** UNION ALL **を使用すると、UNIONよりもコストがかからず、すべての行を単独で戻すことができます。また、** row_number()over()**が必要なソートを生成することは保証されません - ソートを保証するためにEXPLICITオーダーを使用してください。また、参照してください:http://stackoverflow.com/questions/1128737/unpivot-and-postgresql –

+0

あなたの '支払いグループ'の番号を追加することができます:) – flutter

+0

要求通りに空白を追加しました。 – flutter

答えて

1

空白(空文字)付きのバージョン unnest関数がこれを行うことができます。 そして、あなたは空のテキストをしたい場合、あなたは、例えば、ポイントまたはその他のテキスト、または空の文字列の矢印のために、あなたが持っているしたい場合は、この

group | line item | paymentid | customercode |  type  | amount 
-------+-----------+-----------+--------------+-------------------+-------- 
    1 |   1 | PID0001 | CUST024  | PREVIOUS BALANCE | 10000 
    1 |   2 |   |    | PAYMENT AMOUNT | 2500 
    1 |   3 |   |    | REMAINING BALANCE | 7500 
    2 |   1 | PID0002 | CUST031  | PREVIOUS BALANCE | 8500 
    2 |   2 |   |    | PAYMENT AMOUNT | 3500 
    2 |   3 |   |    | REMAINING BALANCE | 5000 
    3 |   1 | PID0003 | CUST005  | PREVIOUS BALANCE | 12000 
    3 |   2 |   |    | PAYMENT AMOUNT | 1500 
    3 |   3 |   |    | REMAINING BALANCE | 10500 

取得するには、この

SELECT ROW_NUMBER() OVER (ORDER BY paymentid) AS "group", 
unnest(array[1, 2, 3]) AS "line item", 
unnest(array[paymentid, '', '']) AS "paymentid", 
unnest(array[customercode, '', '']) AS "customercode", 
unnest(array['PREVIOUS BALANCE', 'PAYMENT AMOUNT', 'REMAINING BALANCE']) AS "type", 
unnest(array[previousbalance, paymentamount, remainingbalance]) AS "amount" 
FROM payment_info 
ORDER BY 1, 2 ; 

を使用することができますunnestで簡単にこれを行うことができます。

4つの空のテキスト値を個別に制御できます。

SELECT ROW_NUMBER() OVER (ORDER BY paymentid) AS "group", 
unnest(array[1, 2, 3]) AS "line item", 
unnest(array[paymentid, '  a', '  c']) AS "paymentid", 
unnest(array[customercode, '  b', '  d']) AS "customercode", 
unnest(array['PREVIOUS BALANCE', 'PAYMENT AMOUNT', 'REMAINING BALANCE']) AS "type", 
unnest(array[previousbalance, paymentamount, remainingbalance]) AS "amount" 
FROM payment_info 
ORDER BY 1, 2 ; 

group | line item | paymentid | customercode |  type  | amount 
-------+-----------+-----------+--------------+-------------------+-------- 
    1 |   1 | PID0001 | CUST024  | PREVIOUS BALANCE | 10000 
    1 |   2 |  a |  b  | PAYMENT AMOUNT | 2500 
    1 |   3 |  c |  d  | REMAINING BALANCE | 7500 
    2 |   1 | PID0002 | CUST031  | PREVIOUS BALANCE | 8500 
    2 |   2 |  a |  b  | PAYMENT AMOUNT | 3500 
    2 |   3 |  c |  d  | REMAINING BALANCE | 5000 
    3 |   1 | PID0003 | CUST005  | PREVIOUS BALANCE | 12000 
    3 |   2 |  a |  b  | PAYMENT AMOUNT | 1500 
    3 |   3 |  c |  d  | REMAINING BALANCE | 10500 

を生成するために、それはあなたが知っている、非常に柔軟なソリューションです。

+0

答えに感謝します。私は30以上の列を取得する場合は、この種のクエリ(unnest)を使用することをお勧めですか? – john1717

+0

ただ試してみてください。それは非常に効率的でなければなりません。 – flutter

1

ユニオンクエリを使用する必要はありません。たとえば、3行とクロス結合を使用できます。これには、ソース表を1回だけ通過するという利点があります。データ/クエリは、この結果を生成することを

drop table if exists Table1; 

CREATE TABLE Table1 
    ("paymentid" varchar(7), "customercode" varchar(7) 
    , "previousbalance" int, "paymentamount" int, "remainingbalance" int) 
; 

INSERT INTO Table1 
    ("paymentid", "customercode", "previousbalance", "paymentamount", "remainingbalance") 
VALUES 
    ('PID0001', 'CUST024', 10000, 2500, 7500), 
    ('PID0002', 'CUST031', 8500, 3500, 5000), 
    ('PID0003', 'CUST005', 12000, 1500, 10500) 
; 

select 
     paymentid 
    , customercode 
    , rn 
    , typeof 
    , case when rn = 1 then previousbalance 
      when rn = 2 then paymentamount 
      when rn = 3 then remainingbalance 
     end as Amount 
from Table1 
cross join (select 1 rn , 'previousbalance' typeof 
      union all 
      select 2 , 'paymentamount' 
      union all 
      select 3, 'remainingbalance' 
      ) rns 

:「レイアウト」の欄のブランクはSQLのために良いフィットではありませんので

+----+-----------+--------------+----+------------------+--------+ 
| | paymentid | customercode | rn |  typeof  | amount | 
+----+-----------+--------------+----+------------------+--------+ 
| 1 | PID0001 | CUST024  | 1 | previousbalance | 10000 | 
| 2 | PID0001 | CUST024  | 2 | paymentamount | 2500 | 
| 3 | PID0001 | CUST024  | 3 | remainingbalance | 7500 | 
| 4 | PID0002 | CUST031  | 1 | previousbalance | 8500 | 
| 5 | PID0002 | CUST031  | 2 | paymentamount | 3500 | 
| 6 | PID0002 | CUST031  | 3 | remainingbalance | 5000 | 
| 7 | PID0003 | CUST005  | 1 | previousbalance | 12000 | 
| 8 | PID0003 | CUST005  | 2 | paymentamount | 1500 | 
| 9 | PID0003 | CUST005  | 3 | remainingbalance | 10500 | 
+----+-----------+--------------+----+------------------+--------+ 

は、SQLは、「レポート・ライター」ではないことに注意してくださいあなたが必要に応じてソートしてフィルタリングできるように、結果の上に表示されているように情報を繰り返す必要があります。

+0

がその点に留意しました...あなたの答えに感謝します..しかし、ここで支払グループの列を追加するにはどうすればいいですか? – john1717

+0

それはunnest()関数でも実行できます:) Postgres Elephantができる魔法の多くがあります – flutter

+0

それはそうである必要はありません。 –

関連する問題