首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在MYSQL中连接多个表时缺少一个表中的数据。

在MYSQL中连接多个表时缺少一个表中的数据。
EN

Stack Overflow用户
提问于 2016-11-30 17:16:50
回答 1查看 51关注 0票数 3

我有三张桌子叫gps_stdnt_subj_xref a,gps_st_mark_fa1_fa3 b,gps_st_sa_mark_master c。第一张表格列有科目清单,另两张列有科目、学生及其成绩。在第三表中,我有一些比第二表更多的主题(在第二和第三表中有许多其他公共字段可用)。当我执行下面的查询时,在输出中我只得到了常见主题的详细信息(subject,在第2和第3表中都有)。我对MYSQL不太熟悉(在oracle中,我们通常在字段的末尾为(+)提供可用的附加值,然后它将获取所有数据)。我试着用左联接来获得预期的输出。但它只给出了共同主题的输出。分享查询,请指点。

代码语言:javascript
复制
SELECT a.gps_subject,
       b.gps_st_mrk_gtot,
       b.gps_st_mrk_grade,
       b.gps_st_uid,
       b.gps_st_name,
       c.gps_st_sa_mark
  FROM gps_stdnt_subj_xref a
       LEFT JOIN (gps_st_mark_fa1_fa3 b, gps_st_sa_mark_master c)
          ON (    a.gps_subject = b.gps_st_mrk_subj
              AND b.gps_st_class = a.gps_class
              AND a.gps_subject = c.gps_st_sa_subject
              AND b.gps_st_uid = c.gps_st_sa_id
              AND c.gps_st_sa_class = b.gps_st_class
              AND b.gps_st_dvn = c.gps_st_sa_dvn
              AND a.gps_class = c.gps_st_sa_class)
 WHERE     a.gps_subject_status = 'Y'
       AND b.gps_st_mrk_stat = 'Y'
       AND b.gps_st_class = 'Class_07'
       AND b.gps_st_dvn = '07-C'
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-11-30 22:06:57

好吧,一切都已经说了:

  1. 对于这两个表,您应该一致地使用左联接。
  2. 不要在WHERE条件中应用左侧联接表中的where条件:您将过滤生成的行,并只获得具有匹配行的行

这是我关于结果查询的外观的建议:

代码语言:javascript
复制
SELECT a.gps_subject,
       b.gps_st_mrk_gtot,
       b.gps_st_mrk_grade,
       b.gps_st_uid,
       b.gps_st_name,
       c.gps_st_sa_mark
  FROM gps_stdnt_subj_xref a
       LEFT JOIN ( select * from gps_st_mark_fa1_fa3
   Where gps_st_mrk_stat = 'Y'
       AND gps_st_class = 'Class_07'
       AND gps_st_dvn = '07-C'
) b
On a.gps_subject = b.gps_st_mrk_subj
              AND b.gps_st_class = a.gps_class

        LEFT JOIN gps_st_sa_mark_master c
          ON a.gps_subject = c.gps_st_sa_subject
              AND b.gps_st_uid = c.gps_st_sa_id
              AND c.gps_st_sa_class =b.gps_st_class
              AND b.gps_st_dvn = c.gps_st_sa_dvn
              AND a.gps_class = c.gps_st_sa_class
 WHERE     a.gps_subject_status = 'Y'

我在子查询中按了where条件,并使用了两次左联接。

===========================================================

编辑的:好的,OP用重复的"gps_subject“和所有其他字段空表示了很多行。这些行应该是subject表在其他表上找不到匹配的行。但为什么要重复呢?在再次查看查询之后,它发现" subject“表还包含"class”(gps_class)属性,因此在各个类中重复相同的主题。

原始查询在与"class“字段(gpt_st_class)匹配的字段上的”左联接“表(将其返回到标准的内部联接)上有一个筛选器。

假设OP需要限制'Class_07‘类的结果,我将这个过滤器移到subject表并创建结果表。

代码语言:javascript
复制
SELECT a.gps_subject,
       b.gps_st_mrk_gtot,
       b.gps_st_mrk_grade,
       b.gps_st_uid,
       b.gps_st_name,
       c.gps_st_sa_mark
  FROM gps_stdnt_subj_xref a
       LEFT JOIN ( select * from gps_st_mark_fa1_fa3
                    Where gps_st_mrk_stat = 'Y'
                      AND gps_st_dvn = '07-C'
                 ) b
              On a.gps_subject = b.gps_st_mrk_subj
             AND b.gps_st_class = a.gps_class

       LEFT JOIN (select * from gps_st_sa_mark_master 
                   Where gps_st_sa_dvn = '07-C'     
                 ) c
              ON a.gps_subject = c.gps_st_sa_subject
             AND b.gps_st_uid = c.gps_st_sa_id
             AND a.gps_class = c.gps_st_sa_class
 WHERE a.gps_subject_status = 'Y'
   and a.gps_class='Class_07';

但是,有一点我不清楚:两个“标记”表是为"student_id“连接的。基本上,这意味着,如果我们再次拥有某种链接,就不可能在不匹配来自另一个表的数据的情况下从表返回数据。

除非我们有一个学生表,或者关于这两个标记表中的一个的信息是“完整的”(以便它可以与主题表内部连接),我能想到的最好是:

代码语言:javascript
复制
SELECT a.gps_subject,
       b.gps_st_mrk_gtot,
       b.gps_st_mrk_grade,
       subj_class_stud.gps_st_uid,
       b.gps_st_name,
       c.gps_st_sa_mark
  FROM gps_stdnt_subj_xref a

       INNER JOIN (
         select gps_st_mrk_subj as subj, gps_st_uid as st_uid, gps_st_class st_class
           from gps_st_mark_fa1_fa3
          where gps_st_mrk_stat = 'Y'
            AND gps_st_dvn = '07-C'
          union all 
         select gps_st_sa_subject as subj, gps_st_sa_id as st_uid, gps_st_sa_class as st_class
           from gps_st_sa_mark_master 
          Where gps_st_sa_dvn = '07-C'  
       ) subj_class_stud
              on subj_class_stud.subj=a.gps_subject
             and subj_class_stud.st_class= a.gps_class

       LEFT JOIN ( select * from gps_st_mark_fa1_fa3
                    Where gps_st_mrk_stat = 'Y'
                      AND gps_st_dvn = '07-C'
                 ) b
              On subj_class_stud.subj = b.gps_st_mrk_subj
             AND b.gps_st_class = subj_class_stud.st_class
             and b.gps_st_uid = subj_class_stud.st_uid

       LEFT JOIN (select * from gps_st_sa_mark_master 
                   Where gps_st_sa_dvn = '07-C'     
                 ) c
              ON subj_class_stud.subj = c.gps_st_sa_subject
             AND subj_class_stud.st_uid = c.gps_st_sa_id
             AND subj_class_stud.st_class = c.gps_st_sa_class

 WHERE a.gps_subject_status = 'Y'
   and a.gps_class='Class_07';

最后一点是,当"b“表不匹配时,OP将在结果集中有一些空字段(例如,没有主题)。在"c“表中可能有相同的字段,但我们没有这些信息。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40894360

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档