2014-04-03 47 views
0

這些都是我的表:SQL視圖查詢不能

portal_users(id, first_name, last_name, email, ...,) 
courses(id, name, location, capacity, ...,) 
feedback_questions(id, question, ...,) 
feedback_answers(id, answers, IDquestion, IDuser, IDcourse) 

我想要做這樣的觀點:

course | first_name | last_name | IDuser | IDcourse | question_1 | answer_1 | question_2 | answer_2 

到目前爲止

CREATE VIEW feedback_answers_vw 
as 
SELECT 
fa.id, 
fa.answer, 
fq.question, 
pu.first_name, 
pu.last_name, 
    fa.IDuser, 
fa.IDcourse 
FROM feedback_answers fa 
INNER JOIN feedback_questions fq 
    ON fa.IDquestion = fq.id 
INNER JOIN portal_users pu 
    ON fa.IDuser = pu.id 
INNER JOIN courses cu 
    on fa.IDcourse = cu.id 
GROUP BY 
fa.IDcourse, fa.IDuser 

這只是顯示一個問題及其答案,但不是屬於同一課程和用戶的所有問題。

我可以在SELECT語句

SELECT 
    fa.id, 
    (select question 
     from feedback_questions 
     where id = 1) as question_1, 
    (select question 
     from feedback_questions 
     where id = 2) as question_2, 
    (select question 
     from feedback_questions 
     where id = 3) as question_3, 
    pu.first_name, 
    pu.last_name, 
    fa.IDuser, 
    fa.IDcourse 

像這樣的東西硬編碼,但我想這樣做的正確的方式,所以我不會改變被添加了問題的代碼每次。

編輯: 這是我的表的數據例如:

**Portal users:** 
1, tom, hanks, [email protected], ..., 
2, steven, spielberg, [email protected], ..., 


**Courses:** 
1, quality, california, 30 
2, information technologies, texas, 24 


**Questions:** 
1, How did you find the course?, ..., 
2, Do you want purchase order?, ..., 


**Answers:** 
1, Internet, 1, 1, 1 
2, yes, 2, 1, 1 
3, TV, 1, 2, 1, 
4, no, 2, 2, 1, 
5, Internet, 1, 1, 2 
6, yes, 1, 1, 2 

這是數據的例子,我想在視圖中顯示:

course|first_name|last_name|IDuser|IDcourse|Question_1|Answer_1|Question_2|Answer_2 

---------------------------------------------------------------------------------- 
quality | tom | hanks | 1 | 1 | How did you find the course? | Internet | Do you want purchase order? | yes 

quality | steven | spielberg | 2 | 1 | How did you find the course? | TV | Do you want purchase order? | no 

Information technologies | tom | hanks | 1 | 2 How did you find the course? | Internet | Do you want purchase order? | yes 

回答

0

後一些樣本數據發佈後,很明顯在這裏需要一個數據透視表(在access/excel中被稱爲'crosstab')。我們可以用一些案例陳述來硬編碼選擇,以涵蓋固定數量的問題,但是每次添加或刪除問題時都必須重新解決這個問題。 @drapp在下面有這樣的解決方案。

但是,我們真正想要的是視圖返回的列數隨着問題的數量而增長和縮小。不幸的是,mysql沒有任何內置函數來幫助我們構建一個函數。我在網上找到的最佳解決方案是​​。作者建議動態構建sql select語句然後執行它。這實際上是一個非常優雅的解決方案

面對這個需求,我不會在SQL中完成這項工作。我預見到的問題是,隨着問題數量的增加,將返回越來越多的專欄;你的觀點會很快慢下來,最終完全停止工作。我會嘗試在sql之外轉換數據,可能是在etl工具,應用程序服務器或BI工具中。或者,如果我有能力(而且我從不這樣做),我會切換數據庫引擎。下面是從其他引擎,用於創建數據透視表提供的工具三種解決方法:

+0

顯示回答問題*問題數的用戶數。 I.E. 如果我有3問題和2個用戶回答。顯示6行。每個用戶 3行,行之間的差異是問題,答案 – Toquis

+0

讓我確保我明白了,你想的問題和答案的清單得到顯示爲同一行中對每個問題的答案對列? – Andreas

+0

也許如果你發佈一些樣本數據和你的預期結果,它會有所幫助。這聽起來越來越像你想旋轉桌子。 – Andreas

0

我們剛纔談到的觀點在我DB Design類和我的教授說,你不能在VIEW語句中使用聯接。我不記得爲什麼不,但你的問題看起來很熟悉。

+0

這是錯誤的,沒有任何連接的視圖的目的是什麼? – JonH

+0

我會在明天上課。 – Andrew

0

我不知道你是否真的需要它作爲一個視圖,這裏是一個示例查詢。

如果你看一下在where子句的第一部分,它是基於一個最小的問題ID = 1的話,我認爲加入到課程表和portal_user表來獲得這些字段。由於反饋答案是第一個表格,我們可以立即得到答案,但也可以加入問題表格來獲得問題。

所以,現在,如何簡單地擴展這個查詢的未來的問題?注意後面的LEFT JOIN後面的反饋答案AGAIN,但是這次作爲別名「fa2」(feedback_answers2),並且JOIN子句基於相同的用戶,相同的課程,但僅限於問題ID = 2。然後將fa2.questionID中的問題表加入問題表(別名fq2)。然後另一個完全相同的設置,但問題3.所以在這裏,我什麼都不做,但使用相同的表,但只是不同的別名。他們都開始與問題1,如果有一個問題2,得到它...如果問題3,得到它也根據需要展開,沒有GROUP BY等

所以,現在,如果你只關心您感興趣的單個課程,只需將其添加到最外面的WHERE子句中,其他任何內容都不需要更改。獲取10個問題,複製/粘貼相應問題ID的LEFT-JOIN組件。

SELECT 
     c.name as course, 
     pu.first_name, 
     pu.last_name, 
     fa1.IDUser, 
     fa1.IDCourse, 
     fq1.question as question1, 
     fa1.answers as answer1, 
     fq2.question as question2, 
     fa2.answers as answer2, 
     fq3.question as question3, 
     fa3.answers as answer3 
    from 
     feedback_answers fa1 
     JOIN courses c 
      ON fa1.IDCourse = c.id 
     JOIN portal_users pu 
      ON fa1.IDUser = pu.id 
     JOIN feedback_questions fq1 
      ON fa1.IDquestion = fq1.id 

     LEFT JOIN feedback_answers fa2 
      ON fa1.IDUser = fa2.IDUser 
      AND fa1.IDCourse = fa2.IDCourse 
      AND fa2.id = 2 
      LEFT JOIN feedback_questions fq2 
       ON fa2.IDquestion = fq2.id 

     LEFT JOIN feedback_answers fa3 
      ON fa1.IDUser = fa3.IDUser 
      AND fa1.IDCourse = fa3.IDCourse 
      AND fa2.id = 3 
      LEFT JOIN feedback_questions fq3 
       ON fa3.IDquestion = fq3.id 

    where 
     fa1.id = 1