繁体   English   中英

SQL Left在每个表中有条件地连接多个表和计数值

[英]SQL Left Join Multiple Tables and count values conditionally in each table

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

我有一些表: '调查''问题''会话''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'| 'session_status'

ParentSurvey: 'kp_parent_survey_id'| 'survey_name'

ParentSurveyQuestion: '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

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

您需要更改的另一件事是在子查询中包含您希望在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

我认为你非常接近 - 只需要修复你的连接并在子查询中包含调查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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM