【问题标题】:Invalid reference to FROM-clause entry for table "mdl_user"对表“mdl_user”的 FROM 子句条目的引用无效
【发布时间】:2015-03-06 21:08:06
【问题描述】:

我正在尝试为 Moodle v2.7 数据库(使用 PostgreSQL 9.3)构建所有用户及其特定课程分数的报告。我收到以下错误,并查看了产生的问题和其他示例同样的错误,但它们都没有为我的具体问题提供答案。不确定我在这里忽略了什么。

错误:对表“mdl_user”的 FROM 子句条目的引用无效

SELECT 
    mdl_user.lastname as LastName,
    mdl_user.firstname as FirstName,
    Grr.finalgrade as Grade,
    REPLACE(Grr.itemname,'COURSE: ','') as Course,
    TO_CHAR(TO_TIMESTAMP(Grr.timemodified), 'MM/DD/YYYY') as Completed
FROM
    public.mdl_user LEFT JOIN (
        SELECT 
            mdl_grade_grades.finalgrade,
            mdl_grade_items.itemname,
            mdl_grade_grades.userid,
            mdl_grade_grades.timemodified
        FROM
            public.mdl_grade_items LEFT JOIN public.mdl_grade_grades
                ON public.mdl_grade_items.id = public.mdl_grade_grades.itemid
        WHERE
            mdl_grade_grades.userid = mdl_user.id AND
            mdl_grade_items.itemname LIKE 'COURSE: Lock Out Tag Out: ECP'
    ) AS Grr ON Grr.userid = public.mdl_user.id
ORDER BY
    mdl_user.lastname,
    mdl_user.firstname

【问题讨论】:

  • 您需要将ID 括在引号中吗?它显示为 postgresql postgresql.org/docs/current/static/sql-keywords-appendix.html 的关键字列表,也许用引号括起来会消除这个问题。 作为一般规则,如果您对包含任何列出的关键字作为标识符的命令产生虚假的解析器错误,您应该尝试引用标识符以查看问题是否消失。
  • @xQbert,我认为这不是问题,因为其他更简单的查询以相同的方式使用 ID 字段。但如果它是一个关键字,那么它应该像你所说的那样被引用。我会尝试引用它,如果它修复它会回复你。
  • timemodified的实际数据类型是什么?
  • @xQbert:带引号的标识符是导致悲伤的常见原因,但这里似乎并非如此。

标签: sql postgresql join left-join moodle


【解决方案1】:

@avk 是对的。但还有更多。适当简化的查询:

SELECT u.lastname
     , u.firstname
     , g.finalgrade AS grade
     , right(i.itemname, -8) AS course
     , to_char(to_timestamp(g.timemodified), 'MM/DD/YYYY') AS completed
FROM   public.mdl_user         u
LEFT   JOIN
      (public.mdl_grade_items  i
  JOIN public.mdl_grade_grades g ON g.itemid = i.id
                                AND i.itemname = 'COURSE: Lock Out Tag Out: ECP'
      ) ON g.userid = u.id
ORDER  BY 1,2;
  • 在左操作数应该是直接匹配而不是模式的情况下使用LIKE 是非常错误的。这可能会导致令人困惑的副作用,例如不自觉地解释特殊字符或这个(今天的例子):

  • 您有一个 LEFT JOIN 与右表上的谓词组合,这会将其强制转换为普通的 [INNER] JOIN。我将谓词移至连接子句以解决该问题。相关:

  • 完全替换子查询。您可以在FROM 子句中使用括号来实现您的目标。

  • 不带引号的混合大小写标识符毫无意义。

【讨论】:

  • 这很接近,但不会产生所需的输出。对于mdl_user 表中与括号括起来的JOIN 匹配的任何条目,它会列出该条目两次。一次是课程名称 (itemname),一次是课程名称的 null 值。 mdl_user 表中的所有条目只能列出一次。
  • @druciferre:不应该这样。你确定你在括号内使用mdl_grade_itemsmdl_grade_grades 之间的普通[INNER] JOIN,并且不是 RIGHT JOIN(这可能会导致像你描述的结果)?跨度>
  • 没关系,mdl_user 表中似乎有一个deleted 字段,我需要忽略值为1 的条目。这现在有效。谢谢!
【解决方案2】:

在子选择Grr 中,删除mdl_grade_grades.userid = mdl_user.id
这是导致错误的原因,它已经加入了AS Grr ON Grr.user.id=public.mdl_user.id 行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-29
    • 2019-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多