0

我在正确组合 SQL 语句时遇到了一些麻烦,因为我没有太多的 SQL 经验,尤其是聚合函数。可以肯定地说,我真的不知道在基本 SQL 结构之外我在做什么。我可以进行常规连接,但不能进行复杂连接。

我有一些表格:'Survey''Questions''Session''ParentSurvey''ParentSurveyQuestion'。在结构上,调查可以有问题,可以有启动调查的用户(会话),也可以有一个父调查,其问题被导入当前调查。

我想要做的是在调查表中获取每个调查的信息;它有总问题,已经开始了多少次会议(有条件地,那些尚未完成的),以及家长调查中的问题数量。三个连接表可以但不必包含任何值,如果不包含,则 COUNT 应返回 0。三个表中的公共字段是“survey_id”的变体

到目前为止,这是我的 SQL,我将表结构放在它下面。

 SELECT 
   `kp_survey_id`,
   COALESCE( q.cnt, 0 ) AS questionsAmount,
   COALESCE( s.cnt, 0 ) AS sessionsAmount
   COALESCE( p.cnt, 0 ) AS parentQAmount,
 FROM `Survey`
   LEFT JOIN                    <-- I'd like the count of questions for this survey
      ( SELECT COUNT(*) AS cnt 
      FROM Questions
      GROUP BY kf_survey_id ) q
     ON Survey.kp_survey_id = Questions.kf_survey_id
   LEFT JOIN 
      ( SELECT COUNT(*) AS cnt    <-- I'd like the count of started sessions for this survey
      FROM Session
      WHERE session_status = 'started'  <-- should this be Session.session_status?
      GROUP BY kf_survey_id ) s
     ON Survey.kp_survey_id = Session.kf_survey_id
   LEFT JOIN            
      ( SELECT COUNT(*) AS cnt    <-- I'd like the count of questions in the parent survey with this survey id
      FROM ParentSurvey
      GROUP BY kp_parent_survey_id ) p
     ON Survey.kf_parent_survey_id = ParentSurveyQuestion.kf_parent_survey_id

“kp”前缀表示主键,而“kf”前缀表示外键
结构:

调查: 'kp_survey_id' | 'kf_parent_survey_id'

问题: 'kp_question_id' | 'kf_survey_id'

会话: 'kp_session_id' | 'kf_survey_id' | '会话状态'

家长调查: 'kp_parent_survey_id' | '调查名称'

家长调查问题: 'kp_parent_question_id' | 'kf_parent_survey_id'

每个表中还有其他列,例如“name”或“account_id”,但我认为在这种情况下它们并不重要

我想知道我是否正确执行此操作,或者我是否遗漏了什么。我正在重新利用我在 stackoverflow 上找到的一些代码并对其进行修改以满足我的需求,因为我没有在这个站点上看到超过三个表的条件聚合。

我的预期输出是这样的:

kp_survey_id   |   questionsAmount   |   sessionsAmount   |   parentQAmount  
    1          |         3           |         0          |        3
    2          |         0           |         5          |        3
4

2 回答 2

1

您需要做的一件事是更正您的联接。加入子查询时,需要使用子查询的别名。在您的情况下,您使用的是子查询中使用的表的别名。

您需要更改的另一件事是在子查询的 JOIN 中包含您希望使用的字段。

进行这些更改并尝试运行。您是否收到错误或想要的结果?

SELECT 
   `kp_survey_id`,
   COALESCE( q.cnt, 0 ) AS questionsAmount,
   COALESCE( s.cnt, 0 ) AS sessionsAmount
   COALESCE( p.cnt, 0 ) AS parentQAmount,
 FROM `Survey`
   LEFT JOIN                    <-- I'd like the count of questions for this survey
      ( SELECT kf_survey_id, COUNT(*) AS cnt 
      FROM Questions
      GROUP BY kf_survey_id ) q
     ON Survey.kp_survey_id = q.kf_survey_id
   LEFT JOIN 
      ( SELECT kf_survey_id, COUNT(*) AS cnt    <-- I'd like the count of started sessions for this survey
      FROM Session
      WHERE session_status = 'started'  <-- should this be Session.session_status?
      GROUP BY kf_survey_id ) s
     ON Survey.kp_survey_id = s.kf_survey_id
   LEFT JOIN            
      ( SELECT kp_parent_survey_id, COUNT(*) AS cnt    <-- I'd like the count of questions in the parent survey with this survey id
      FROM ParentSurvey
      GROUP BY kp_parent_survey_id ) p
     ON Survey.kf_parent_survey_id = p.kf_parent_survey_id
于 2013-02-20T20:44:18.010 回答
1

我认为您非常接近 - 只需要修复您的连接并将调查 ID 包含在子查询中以在这些连接中使用:

SELECT 
   `kp_survey_id`,
   COALESCE( q.cnt, 0 ) AS questionsAmount,
   COALESCE( s.cnt, 0 ) AS sessionsAmount
   COALESCE( p.cnt, 0 ) AS parentQAmount,
 FROM `Survey`
   LEFT JOIN                    
      ( SELECT COUNT(*) cnt, kf_survey_id AS cnt 
      FROM Questions
      GROUP BY kf_survey_id ) q
     ON Survey.kp_survey_id = q.kf_survey_id
   LEFT JOIN 
      ( SELECT COUNT(*) cnt, kf_survey_id
      FROM Session
      WHERE session_status = 'started'  
      GROUP BY kf_survey_id ) s
     ON Survey.kp_survey_id = s.kf_survey_id
   LEFT JOIN            
      ( SELECT COUNT(*) cnt, kp_parent_survey_id
      FROM ParentSurvey
      GROUP BY kp_parent_survey_id ) p
     ON Survey.kf_parent_survey_id = p.kp_parent_survey_id
于 2013-02-20T20:45:44.420 回答