【问题标题】:SQL view query not workingSQL 视图查询不起作用
【发布时间】:2014-05-16 00:10:25
【问题描述】:

这些是我的桌子:

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, tom_hanks@example.com, ..., 
2, steven, spielberg, steven@example.com, ...,


**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

【问题讨论】:

    标签: mysql sql database sql-view


    【解决方案1】:

    我们刚刚在我的数据库设计课上讨论了视图,我的教授说你不能在 VIEW 语句中使用连接。我不记得为什么不,但你的问题看起来很熟悉。

    【讨论】:

    • 这是错误的,没有任何连接的视图的目的是什么?
    • 明天上课问。
    【解决方案2】:

    我不知道您是否真的需要它作为视图,这里有一个示例查询。

    如果您查看 where 子句的第一部分,它基于最小问题 ID = 1。然后我将其连接到 course 表和 portal_user 表以获取这些字段。由于反馈答案是第一个表,因此我们可以立即得到该答案,还可以加入问题表以获取问题。

    那么现在,如何简单地扩展此查询以解决未来的问题?请注意 LEFT-JOIN 紧随其后的反馈答案 AGAIN,但这次是别名“fa2” (feedback_answers2),并且 JOIN 子句基于相同的用户、相同的课程,但仅适用于问题 ID = 2。这然后将 fa2.questionID 上的问题表连接到问题表(别名 fq2)。然后是另一个完全相同的设置,但对于问题 3。所以在这里,我什么都不做,只是使用相同的表,只是使用不同的别名。都是从第1题开始,如果有第2题,就搞定……如果有第3题,也搞定,按需扩展,不分组等等。

    所以现在,如果您只关心您感兴趣的一门课程,只需将其添加到最外面的 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
    

    【讨论】:

      【解决方案3】:

      发布一些示例数据后,很明显这里需要一个数据透视表(在 access/excel 中称为“交叉表”)。我们可以用一些案例语句对选择进行硬编码以涵盖固定数量的问题,但是每次添加或删除问题时都必须重新访问该解决方案。 @drapp 下面有这样的解决方案。

      然而,我们真正想要的是视图返回的列数随着问题的数量而增长和缩小。不幸的是,mysql没有任何内置函数来帮助我们构建一个。我在网上找到的最佳解决方案是http://www.artfulsoftware.com/infotree/qrytip.php?id=523。作者建议动态构建 sql select 语句然后执行它。这实际上是一个非常优雅的解决方案。

      面对这个要求,我不会在 SQL 中做这项工作。我预见的问题是,随着问题数量的增加,返回的列会越来越多;您的视图会很快减速到爬行,并最终完全停止工作。我会尝试在 sql 之外转换数据,可能在 etl 工具、应用程序服务器或 BI 工具中。

      或者,如果我有能力(而且我从来没有),我会切换数据库引擎。以下是来自其他引擎的三种解决方案,它们提供了用于创建数据透视表的工具:

      【讨论】:

      • 显示回答问题的用户数 * 问题数。 IE。如果我有 3 个问题和 2 个用户回答。显示 6 行。每个用户 3 行,行之间的区别是问题和答案
      • 请确保我理解,您希望问题和答案列表显示在同一行中,每个问题答案对都有列?
      • 也许如果您发布一些示例数据和您的预期结果会有所帮助。听起来越来越像您想要旋转表格。
      • 谢谢,我只是用数据示例编辑问题
      猜你喜欢
      • 2017-04-09
      • 1970-01-01
      • 1970-01-01
      • 2013-11-15
      • 2011-04-13
      • 2013-02-03
      • 1970-01-01
      • 1970-01-01
      • 2015-11-13
      相关资源
      最近更新 更多