Select
SQL 中的自定義 CSV“報告”
我有兩個從 ERP(發票)中提取的 SQL 數據表,第一個包含發票的“head”(invoice_number、date、customer,…),第二個表包含所有發票的“行”(good_description,qty , 價錢, …)
簡化:
T1.ID | T1.COL_A | T1.COL_B T2.T1_ID | T2.COL_A | T2.COL_B ----------------------------- ------------------------------- 1 | AAA | BBB 1 | eee | fff 2 | CCC | DDD 1 | ggg | hhh 2 | iii | jjj 2 | kkk | lll
如果我
SELECT
按欄位連接兩個表,ID
它將給出:T1.COL_A | T1.COL_B | T2.COL_A | T2.COL_B ---------------------------------------------- 1 AAA | BBB | eee | fff 1 AAA | BBB | ggg | hhh 2 CCC | DDD | iii | jjj 2 CCC | DDD | kkk | lll
好的很簡單。
問題是我需要一種特定的格式來將數據導入另一個 ERP,一種像這樣製作的 CSV 格式:
ROW_TIPE ; T1.COL_A ; T1.COL_B ; T2.COL_A ; T2.COL_B ---------------------------------------------------------------- INVOICE_HEAD ; AAA ; BBB ; ; INVOICE_ROW ; ; ; eee ; fff INVOICE_ROW ; ; ; ggg ; hhh INVOICE_HEAD ; CCC ; DDD ; ; INVOICE_ROW ; ; ; iii ; jjj INVOICE_ROW ; ; ; kkk ; lll
因此,這些行被“分組”並且不重複,並且在第一列插入了要由 ERP 處理的行類型,以導入數據(如果是
INVOICE_HEAD
或INVOICE_ROW
)在 SQL 中實現此結果的最佳方法是什麼?
數據來自 Pervasive Btrieve。我設法從兩個 CSV 文件(每個表一個)中提取發票數據。然後我導入了一個 SQLite 來進行所需的操作,以獲得可以在新的 ERP 軟體中導入的格式。
我可以建議使用視圖嗎?考慮下表(和測試數據):
-- T1 create table ihead ( id number primary key , col_a varchar2(32) , col_b varchar2(32) ); -- T2 create table irow ( headid number references ihead(id) , col1 varchar2(32) , col2 varchar2(32) , irowid number primary key );
在第二個表(您稱為 T2)中,應該以某種方式對行進行編號,否則將很難將發票詳細資訊按正確的順序排列 - 正如@Bill 所暗示的那樣。
-- test data begin insert into ihead values (1, 'AAA', 'BBB'); insert into ihead values (2, 'CCC', 'DDD'); insert into irow values (1, 'eee', 'fff', 1); insert into irow values (1, 'ggg', 'hhh', 2); insert into irow values (2, 'iii', 'jjj', 3); insert into irow values (2, 'kkk', 'lll', 4); end;
我會先創建一個連接,並將其儲存為視圖,如下所示:
-- join, similar to the first select you have written create or replace view alldetails as select H.id, H.col_a, H.col_b, R.col1, R.col2, R.irowid from ihead H join irow R on id = headid;
檢查輸出:
select * from alldetails; -- output ID COL_A COL_B COL1 COL2 IROWID 1 AAA BBB eee fff 1 1 AAA BBB ggg hhh 2 2 CCC DDD iii jjj 3 2 CCC DDD kkk lll 4
第二種視圖:獲取所有INVOICE_HEADS(第一次選擇),然後INVOICE_ROWS(第二次選擇)
create or replace view idetails (c1, c2, c3, c4, irow) as select 'INVOICE_HEAD', col_a, col_b, col1, col2 from alldetails where irowid in ( select min(irowid) from iheader group by id ) union select 'INVOICE_ROW', null, null, col1, col2 from alldetails where irowid not in ( select min(irowid) from iheader group by id )
現在我們可以:
select * from idetails order by irow -- output C1 C2 C3 C4 IROW INVOICE_HEAD AAA BBB eee fff INVOICE_ROW - - ggg hhh INVOICE_HEAD CCC DDD iii jjj INVOICE_ROW - - kkk lll
通過執行以下命令獲得最終輸出:
select c1 ||';'|| c2 ||';'|| c3 ||';'|| c4 ||';'|| irow from idetails order by irow -- final output (some padding added manually, -- but can be done with RPAD or LPAD) INVOICE_HEAD ; AAA ; BBB ; eee ; fff INVOICE_ROW ; ; ; ggg ; hhh INVOICE_HEAD ; CCC ; DDD ; iii ; jjj INVOICE_ROW ; ; ; kkk ; lll
更新 2017-05-17(要求已更改)
-- leave the first view as it is, -- change the second view to be: create or replace view idetails ( c1, c2, c3, id, c4, c5, irowid ) as select distinct 'INVOICE_HEAD', col_a, col_b, headid, null, null, 0 from alldetails union select 'INVOICE_ROW', null, null, headid, col1, col2, irowid from alldetails;
然後,選擇您需要的所有列(注意:ORDER BY 子句中有 2 列):
select c1 ||';'|| c2 ||';'|| c3 ||';'|| c4 ||';'|| c5 from idetails order by id, irowid;
輸出(為清楚起見,手動添加填充):
INVOICE_HEAD;AAA;BBB; ; INVOICE_ROW ; ; ;eee;fff INVOICE_ROW ; ; ;ggg;hhh INVOICE_HEAD;CCC;DDD; ; INVOICE_ROW ; ; ;iii;jjj INVOICE_ROW ; ; ;kkk;lll