将引用表连接到基表以外的表

时间:2016-05-09 08:06:29

标签: mysql

基本上我有一个查询如下:

SELECT MAIN.response_id AS 'Response Id', 
    CONCAT(CASE 
        WHEN MAIN.months = 'Jan - Mar' THEN 'March'
        WHEN MAIN.months = 'Apr - Jun' THEN 'June'
        WHEN MAIN.months = 'Jul - Sep' THEN 'September'
        WHEN MAIN.months = 'Oct - Dec' THEN 'December'
        ELSE 'Error'
    END, ' ', MAIN.Year) AS Period,
    CNT.country_name AS Country, INITM.num_modules AS 'Initial Training - Number of Modules', INITTRAINED.num_instr AS 'Initial Training - Instructors Trained', INITPASS.pass_num AS 'Initial Training - Instructors Passed', INITPASS.pass_num / INITTRAINED.num_instr AS 'Initial Training - Pass Percentage'
FROM responses_main AS MAIN -- Main responses table
LEFT OUTER JOIN responses_init_training_modules AS INITM USING (response_id) -- Main INIT training table
LEFT OUTER JOIN responses_init_training_pass_num AS INITPASS USING (response_id) -- Main INIT training table
LEFT OUTER JOIN responses_init_training_instr_trained AS INITTRAINED USING (response_id) -- Main INIT training table
LEFT OUTER JOIN country AS CNT ON MAIN.country_id = CNT.country_id -- Country table
GROUP BY MAIN.response_id, MAIN.months + ' ' + MAIN.Year, CNT.country_name

此查询缺少的是程序表的连接。每个引用的表(INITM,INITPASS和INITTRAINED)都有一个program_id引用程序表,但是基表(MAIN)与程序表无关。当前查询导致一个表只返回第一个program_id的数据+不显示任何程序信息。

如何导出显示MAIN.response_id,PROG.program_id,INITM.num_modules,INITPASS.pass_num和INITTRAINED.instr_trained的数据集?我无法弄清楚如何使用来自3个引用表的数据来获取引用两个维度(MAIN和PROG)的表。

我已经完成了我想在这里实现的目标:

image

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

看起来您的数据结构造成了困难..我假设您的3 responses_init_*responses_main的子类。

假设一个响应仅适用于一个程序,我可能会通过将所有program_id列移到responses_main表并从那里开始来实现此目的:

    SELECT ...
      FROM program p
      JOIN responses_main rm
        ON rm.program_id = p.program_id 
 LEFT JOIN responses_init_training_modules ritm
        ON ritm.response_id = rm.response_id 
 LEFT JOIN responses_init_training_pass_num ritpn
        ON ritpn.response_id = rm.response_id 
 LEFT JOIN responses_init_training_instr_trained ritit
        ON ritit.response_id = rm.response_id
       ...

注意:

  • 我决定使用单个和复数表名(responsesprogram
  • 如果您使用的是季度,请将其另存为TINYINT,或将该范围的开头和结尾存储为TINYINT月份或DATE。将任何类型的范围存储为连字符分隔字符串将在以后为您提供问题。

<强>更新

与您的DBA交谈,解释您的需求,看看他是否会为您更改它,这是有道理的。

同时,运行三个连接以分别编程:

LEFT JOIN program ritmp
       ON ritmp.program_id = ritm.program_id
LEFT JOIN program ritpnp
       ON ritpnp.program_id = ritpn.program_id
LEFT JOIN program rititp
       ON rititp.program_id = ritit.program_id

或者您可以使用:

(LEFT) JOIN program p ON p.program_id = COALESCE(ritm.program_id, ritpn.program_id, ritit.program_id)

但它会变慢,我会推荐它作为最后的手段。