从父级访问SQL子查询访问字段

时间:2017-07-18 21:02:35

标签: sql ms-access

我有一个适用于Access 2016的SQL查询:

SELECT
    Count(*) AS total_tests,
    Sum(IIf(score>=securing_threshold And score<mastering_threshold,1,0)) AS total_securing,
    Sum(IIf(score>=mastering_threshold,1,0)) AS total_mastering,
    total_securing/Count(*) AS percent_securing,
    total_mastering/Count(*) AS percent_mastering,
    (Count(*)-total_securing-total_mastering)/Count(*) AS percent_below,
    subjects.subject,
    students.year_entered,
    IIf(Month(Date())<9,Year(Date())-students.year_entered+6,Year(Date())-students.year_entered+7) AS current_form,
    groups.group

FROM
    ((subjects
        INNER JOIN tests ON subjects.ID = tests.subject)
            INNER JOIN (students
                INNER JOIN test_results ON students.ID =   test_results.student) ON tests.ID = test_results.test)
    LEFT JOIN
        (SELECT *  FROM group_membership LEFT JOIN groups ON group_membership.group = groups.ID) As g
    ON students.ID = g.student

GROUP BY subjects.subject, students.year_entered, groups.group;

但是,我想在加入我的桌子之前过滤掉不相关的组。表groups有一个列subject,它是一个外键。

当我尝试将ON students.ID = g.student更改为ON students.ID = g.student And subjects.ID = g.subject时,我收到错误&#39; JOIN表达式不受支持&#39;。

或者,当我尝试将WHERE subjects.ID = groups.subject添加到子查询时,它会询问subjects.ID的参数值,尽管它是父查询中的列。

谷歌搜索显示许多类似的错误,但它们都通过更改括号来解决。那没有用。

以防表关系有用:

table relationships

谢谢。

编辑:https://www.dropbox.com/s/yh80oooem6gsni7/student%20tracker.ACCDB?dl=0

的示例数据库

4 个答案:

答案 0 :(得分:1)

我没有要测试的数据库,但我会使用 subject 表作为子查询:

(SELECT * FROM subject WHERE 过滤掉你不需要的东西 Subj

然后INNER在您的查询中加入这个新的 Subj 表,该表将排除不相关的组。

此外,我永远不会在 WHERE 子句( WHERE subjects.ID = groups.subject )中创建连接,这会创建笛卡儿product(具有subjects.ID和groups.subject的所有可能组合的表)然后它过滤掉记录以满足您的连接。处理大量数据时可能需要永久或崩溃。

与&#34;相关的错误可能不支持加入表达式&#34 ;;在这些字段中数据类型是否匹配?

答案 1 :(得分:1)

具有多个连接的MS Access查询很难仅通过SQL进行更新,因为与其他RDBMS不同,需要进行parenetheses配对,并且这些配对必须遵循顺序。而且,一些配对甚至可以嵌套。因此,对于初学者,建议使用MS Office应用程序中的查询设计GUI构建具有复杂和多个连接的查询,并让它构建SQL。

对于g派生表上的简单过滤器,您可以在派生表g上过滤主题,但您可能希望所有主题< / EM>:

...
(SELECT * FROM group_membership 
 LEFT JOIN groups ON group_membership.group = groups.ID
 WHERE groups.subject='Earth Science') As g
...

因此,对于所有主题,请考虑在GUI中从头开始重新构建查询,该查询几乎反映了实际上自动链接GUI中的联接的表关系。然后,删除不需要的表。

  1. 通常您希望从联接表开始,或者设置为 groups group_membership tests test_results 。实际上,请考虑将g派生表保存为自己的查询。
  2. 然后添加不同的记录主要源表,如学生主题
  3. 您甚至可能需要在FROMJOIN子句中使用订单来获得所需的结果,甚至可能在查询中添加相同的表格。并且要小心将group_membership(两个一对多链接)等连接表添加到GROUP BY查询,因为它会导致重复记录聚合。因此,您可能需要按主题加入聚合查询。
  4. 除非您可以发布所有表格的内容,否则从我们的角度来看,很难从此处获得帮助。

答案 2 :(得分:1)

您的子查询g使用LEFT JOIN,但两个表之间存在强制1:n关系,因此总会有匹配的组。改为使用INNER JOIN。

使用g.subject,您正尝试加入左侧联接右侧的列,但该行无法正常工作。

此外,您不应在具有相同列名的表的连接上使用SELECT *。仅包括您需要的合格列名称。

LEFT JOIN
    (SELECT group_membership.student, groups.group, groups.subject
     FROM group_membership INNER JOIN groups 
       ON group_membership.group = groups.ID) As g
ON (students.ID = g.student AND subjects.ID = g.subject)

我会调用group_membership group_IDstudent_ID中的列以避免混淆。

答案 3 :(得分:0)

我通过(大量的试验和错误)解决了这个问题,并在此处提出建议,以便在GUI中进行查询并加入它们。最终结果是4个深度查询!如果数据库更大,性能会很糟糕......但现在它的工作我最终可以调整它。

谢谢大家!