2016-12-05 48 views
0

我試圖多次運行一個查詢 - 每次都有一個關於「where」語句的略有不同的規範。 我想寫一個單一的查詢,並要求數據庫逐步執行每個規格,並將相應的輸出保存爲csv.file。 我不知道如何開始。執行不同規格的PosgreSQL查詢並保存結果

的基本查詢如下:

SELECT 
select id, 
count(DISTINCT (a.id, c.publn_id)) as count 
from a 
join b on a.appln_id=b.appln_id 
join c on b.publn_id=c.cit_id 
left outer join d on c.publn_id=d.publn_id 
group by id 

我想運行下面的其他規格(注意在選擇和組修改通過,除了那裏的條件是必要的語句):

1.

SELECT 
select id, c.auth, 
count(DISTINCT (a.id, c.publn_id)) as count 
from a 
join b on a.appln_id=b.appln_id 
join c on b.publn_id=c.cit_id 
left outer join d on c.publn_id=d.publn_id 
where (c.auth='EP' or c.auth='US') 
group by id, c.auth 

2.

SELECT 
select id, d.categ, 
count(DISTINCT (a.id, c.publn_id)) as count 
from a 
join b on a.appln_id=b.appln_id 
join c on b.publn_id=c.cit_id 
left outer join d on c.publn_id=d.publn_id 
where c.auth='EP' 
and (d.categ='X' or d.categ='Y') 
group by id, d.categ 

3.

SELECT 
select id, d.categ, 
count(DISTINCT (a.id, c.publn_id)) as count 
from a 
join b on a.appln_id=b.appln_id 
join c on b.publn_id=c.cit_id 
left outer join d on c.publn_id=d.publn_id 
where c.auth='EP' 
and (d.categ='E') 
group by id, d.categ 

4.

SELECT 
select id, 
count(DISTINCT (a.id, c.publn_id)) as count 
from a 
join b on a.appln_id=b.appln_id 
join c on b.publn_id=c.cit_id 
left outer join d on c.publn_id=d.publn_id 
where c.auth='EP' 
and (d.categ!='Y' and d.categ!='X' and d.categ!='E') 
group by id 

此外,每個規範將被用於查詢不同時間窗口(但我離開這些條件了現在)。

我想指定一個循環遍歷所有規格的單個查詢,然後自動保存結果。

+0

'UNION ALL'可能是你想要的嗎?可能與'FROM'或CTE('WITH'查詢)中的子查詢結合? –

+0

謝謝,我不確定'UNION ALL'如何提供幫助,你能舉個例子嗎?我正在考慮創建一個臨時表,然後用不同的條件指定不同的SELECTS。但是,我正在尋找一個解決方案,您只需指定一個基本的SELECT語句,其中包含一個包含不同條件的循環。我想得到的是每個規範的一個CSV文件:使用where =(c.auth ='EP'或c.auth ='US'),c.auth ='EP' 和( d.categ ='X'或d.categ ='Y')...,使用基本查詢開始循環(應用不同的條件),之後保存文件 –

回答

1

嘗試使用特殊要求COPY (SELECT ...) TO file WITH CSV HEADER;

Like this one COPY (SELECT * FROM country WHERE country_name LIKE 'A%') TO '/usr1/proj/bray/sql/a_list_countries.copy'; 只需向內部請求添加所需的所有參數並運行查詢即可。

更多信息:https://www.postgresql.org/docs/current/static/sql-copy.html

+0

謝謝。使用CSV複製(選擇...)到標準輸出正在工作,但標準輸出是必要的,否則你必須是超級用戶。但我不知道結果CSV文件將保存在哪裏,也不知道在哪個名稱下。我怎樣才能指定這個?順便說一句,我讀過,也可以使用\ COPY反斜槓,但這給了我一個錯誤,並沒有運行。 –

+0

要輸出到一個文件,你需要一個允許postgres寫入的文件夾。例如在'/ tmp'中,當然最好使用普通文件夾。 我認爲從另一臺主機連接並輸出到stdout會更舒服,重定向到本地文件。像'psql -h主機-U用戶'COPY(SELECT * FROM country WHERE country_name LIKE'A%')to stdout WITH CSV HEADER'> file.csv' –

+0

'\ copy'只能在'psql'客戶端中使用。 –

0

所以,每明確的意見,你想多輸出文件。這是關鍵的缺失信息。

你不能用SQL查詢來做到這一點。

可以用PL/pgSQL的過程做到這一點 - 一個函數或DO塊 - 但前提是你有寫權限的服務器上的文件,因爲你必須使用COPY到一個指定的文件編寫不同文件在LOOP。您將創建一個臨時表來預先計算結果,然後使用COPY(SELECT ... FROM temptable ... WHERE ...)到'somefilename')的變體重複查詢以寫入結果。

否則,您需要使用客戶端腳本執行此操作,因爲服務器無法爲單個查詢中的copy ... to stdout指定所需的輸出文件名,也無法分割多個copy

例如,您可以編寫一個與psql一起運行的腳本,該腳本創建了temporary表,然後使用\copy來編寫輸出文件。

或者您可以使用perl的DBD :: Pg,Python的psycopg2或任何客戶端驅動程序來查詢和複製輸出。