sql - 缺少表的 FROM 子句条目

标签 sql database postgresql greatest-n-per-group

我编写了以下 SQL 语句来从 gendataTrainingMatrix 两个表中获取数据:

SELECT * FROM (SELECT DISTINCT ON ("TrainingMatrix".payroll, "TrainingName", "Institute")"gendata"."Employee Name","gendata"."Position", "gendata"."Department",  "TrainingMatrix".* 
FROM "TrainingMatrix" JOIN "gendata" ON "TrainingMatrix".payroll = "gendata".payroll 
ORDER  BY payroll, "TrainingName", "Institute" ,"TrainingDate" DESC NULLS LAST) AS foo;

它工作正常,但我需要通过以下方式更多地过滤记录:

WHERE "TrainingMatrix"."ExpiryDate" - current_date <= 0 
AND  EXTRACT(YEAR FROM  "TrainingMatrix"."ExpiryDate") = EXTRACT(YEAR FROM current_date);

因此,原始 SQL 语句将是:

SELECT * FROM (SELECT DISTINCT ON ("TrainingMatrix".payroll, "TrainingName", "Institute")"gendata"."Employee Name","gendata"."Position", "gendata"."Department",  "TrainingMatrix".* 
FROM "TrainingMatrix" JOIN "gendata" ON "TrainingMatrix".payroll = "gendata".payroll 
ORDER  BY payroll, "TrainingName", "Institute" ,"TrainingDate" DESC NULLS LAST) AS foo WHERE "TrainingMatrix"."ExpiryDate" - current_date <= 0 
AND  EXTRACT(YEAR FROM  "TrainingMatrix"."ExpiryDate") = EXTRACT(YEAR FROM current_date);

但是我得到了这个错误:

ERROR: missing FROM-clause entry for table "TrainingMatrix" LINE 3: ...te" ,"TrainingDate" DESC NULLS LAST) AS foo WHERE "TrainingM...

我正在使用 PostgreSQL。大家有什么建议吗?

最佳答案

100% 什么 @a_horse already said .加上更多的东西:

  • 格式化您的查询,以便在您尝试调试之前易于阅读和理解。更重要的是,在您在公共(public)论坛上发帖之前。

  • 使用 table aliases ,尤其是您不幸的 CaMeL 大小写名称,以使其更易于阅读。

  • 在您的查询中提供您的表定义或至少 table-qualify 列名称,以便我们有机会对其进行解析。您的直接问题已在下面的查询中解决。您还可以相应地替换 ?.:

    • t .. “TrainingMatrix”
    • 的别名
    • g .. gendata
    • 的别名

SELECT *
FROM  (
    SELECT DISTINCT ON (t.payroll, ?."TrainingName", ?."Institute")
           g."Employee Name", g."Position", g."Department",  t.* 
    FROM   "TrainingMatrix" t
    JOIN   gendata          g  ON g.payroll = t.payroll 
    ORDER  BY t.payroll, ?."TrainingName", ?."Institute"
         , ?."TrainingDate" DESC NULLS LAST
    ) AS foo
WHERE  foo."ExpiryDate" - current_date <= 0 
AND    EXTRACT(YEAR FROM  foo."ExpiryDate") = EXTRACT(YEAR FROM current_date);

但还有更多。

  • 如@a_horse 所写,使用必须一直用双引号引起来的非法标识符是个坏主意。但是 带有空格的标识符 字符更糟糕:“员工姓名”。这距离自制 SQL 注入(inject)仅一步之遥。

  • 您的附加过滤器的措辞方式不利于性能

    WHERE  "ExpiryDate" - current_date <= 0 
    

    不是sargable因此不能使用普通索引。撇开这一点不谈,它也比需要的更贵。改用:

    WHERE "ExpiryDate" >= current_date
    

    类似于您的第二个表达式,应将其重写为:

    WHERE  "ExpiryDate" >= date_trunc('year', current_date)
    AND    "ExpiryDate"  < date_trunc('year', current_date) + interval '1 year'
    

    结合两者,我们可以去除多余的表达式:

    WHERE  "ExpiryDate" >= current_date
    AND    "ExpiryDate"  < date_trunc('year', current_date) + interval '1 year'
    
  • 您的问题不明确。您要在 DISTINCT 之前还是之后应用附加过滤器?不同的结果。
    假设 before DISTINCT,您不需要子查询 - 这消除了您当前问题的原因:子查询没有不同的别名。

一起:

SELECT DISTINCT ON (t.payroll, "TrainingName", "Institute") 
       g."Employee Name", g."Position", g."Department", t.* 
FROM   "TrainingMatrix" t
JOIN   gendata          g USING (payroll)
WHERE  t."ExpiryDate" >= current_date
AND    t."ExpiryDate" <  date_trunc('year', current_date) + interval '1 year'
ORDER  BY t.payroll, "TrainingName", "Institute", "TrainingDate" DESC NULLS LAST

关于sql - 缺少表的 FROM 子句条目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19975755/

相关文章:

php - 如何将连接表的结果数组存储在mysql的行结果中?

表中的sql层次结构

python - 如何将数据库中的特定行保存到新的 Excel 文件中?

database - Golang DB反/序列化方法(数据库/sql之上的sqlx)

c# - 如何禁用 MARS 并规避 "MARS is not yet implemented"-exception”?

mysql - SSRS 提示使用 unxtimestamp 处理 mysql 数据库

mysql - 3 个查询的输出

database - Scala-Slick 中外键的类型投影

具有不同列的两个表的 SQL 并集

postgresql split_part - 如何在第一个拆分键之后拆分