2016-06-29 52 views
0

執行select查詢我有一個表名test使用一個表作爲一項規則,而在其他表

first  last 
raj   kumar 
raj  patel 

有數百行的這個表。

我有另一個表class所有的名字都出現在test表和它的標記爲每個主題。

class_id first_name last_name subject  marks 
1  raj   kumar  physics 70 
1  raj   kumar  chemistry 70 
1  raj   patel  physics 80 
1  raj   kumar  math  90 
1  raj   kumar  computer 80 
1  raj   patel  chemistry 90 
1  raj   patel  math  100 
2  raj   kumar  physics 70 
2  raj   kumar  chemistry 70 
2  raj   patel  physics 80 
2  raj   kumar  math  90 
2  raj   kumar  computer 80 
2  raj   patel  chemistry 90 
2  raj   patel  math  100 

現在我想知道每個學生存在於以下格式test表的總標記。

class_id raj.kumar raj.patel 
1   310   270 
2   n    m 

所以會有n數列中所產生的tbale

對於這種特殊情況下,我們可以寫

select class_id 
    sum(case when first_name = 'raj' and last_name = 'Kumar' then marks else 0) as "raj.kumar", 
    sum(case when first_name = 'raj' and last_name = 'patel' then marks else 0)as "raj.patel" 
    from class 
    group by class_id 

由於學生人數是不固定的,其存在於test表。所以我不想在我的查詢中硬編碼姓和名。 我想要這樣的東西,可以計算所有在test桌上的學生的分數。

select class_id, 
    for(i = 0; i < test.size; i++) 
    sum(case when first_name = i.first and last_name = i.last then marks else 0) as i.first|| '.' ||i.last, 
    from class 
    group class_id 

如何編寫查詢或存儲過程爲此 在此先感謝。

我正在使用postgresql。

+0

檢查[此答案](http://stackoverflow.com/a/35447184/593144)。你的情況可能是'select ct('select * from test','class_id','first_name || last_name','marks','ct_cur');在ct_cur中獲取所有內容;' – Abelisto

回答

0

對於所有學生?

什麼是錯的:

select class_id, first_name, last_name, sum(marks) 
    from class 
group by class_id, first_name, last_name; 

所以,你想一個交叉。這裏主要的問題是規劃師在開始之前需要知道有多少列和什麼類型。所以壞消息是沒有直接的方法來做到這一點。

所以,你有幾個選擇:

  1. 看看tablefunc延伸和動態生成圍繞crosstab()功能
  2. 使用xmljson類型和返回對象或文件而不是記錄查詢。
  3. 使用我的上面的查詢和像excel這樣的客戶端工具來爲你做交叉表。
  4. (編輯)您可以在存儲過程中動態生成SQL,並返回一個refcursor,但這會將您的「客戶端」代碼生成轉移到函數中,回到問題中。

編輯要清楚你的問題是規劃師的限制。您不能將列列表擴展到可變數量的列中。所以你必須從db外部生成SQL。 您無法直接在SQL中處理動態數量的列。

現在,我強烈建議使用tablefunc擴展中的crosstab()函數,因爲這在概念上簡化了結果。如果您必須手動執行此操作(請不要),您可以通過從另一個表中選擇,在pl/perl或pl/pgsql中編寫查詢生成器,然後將pl/pgsql的EXECUTE用於光標。您可以返回refcursor.這並不理想,因爲客戶端必須從返回的refcursor中獲得FETCH

所以你的第一點是決定你要在哪裏生成將運行的SQL代碼。這將在數​​據庫客戶端?或者在動態SQL中(要求客戶端FETCH行與運行函數分開)?

+0

但我想要的表格格式不同。我希望所有的名字都出現在列中,正如我上面提到的那樣。所以請指導我編寫查詢來實現這一點。謝謝 –

+0

啊,所以你想要一個交叉表 –

+0

這可以在沒有進入交叉表的情況下通過CASE語句來實現。我已經爲這個特定的案例寫了同樣的查詢,但是我希望在測試表的幫助下生成case語句。這也是在循環的幫助下在最後一部分提到的。但如何寫相同的查詢,這是我的關注點..謝謝。 –

相關問題