【问题标题】:SQL column reference is invalidSQL 列引用无效
【发布时间】:2013-03-12 17:29:22
【问题描述】:

我正在使用 Jaspersoft 的 iReport 创建一个报告,该报告将从我的 Maintenance Assistant CMMS 数据库中提取数据。数据库位于本地主机上,我没有创建任何表或列。 MA CMMS 负责这一点。我只想把数据拉到一个报告中。

这是我的代码:

SELECT * 
FROM   "tblworkordertask" 
WHERE  "dbltimespenthours" > 0 
       AND "dtmdatecompleted" BETWEEN $P{DATE_FROM} AND $P{DATE_TO}
GROUP  BY "intworkorderid" 

我的错误:

原因:java.sql.SQLSyntaxErrorException:列引用“tblWorkOrderTask.id”无效,或者是无效表达式的一部分。对于带有 GROUP BY 的 SELECT 列表,被选择的列和表达式可能仅包含有效的分组表达式和有效的聚合表达式。

我不知道为什么错误是指“tblWorkOrderTask.id”,因为我没有这样的列,也没有要求该列。

如果我取出 group by 子句,它可以正常工作,但正如您所料,我会使用相同的 WorkOrderID 获得多个结果。我想按此列分组,然后统计结果。我尝试使用 SELECT DISTINCT,但随后我收到有关未选择列的错误。

【问题讨论】:

  • tblWorkOrderTask 中有哪些字段?
  • 我现在不在工作,但我一定会为您查找。我知道我只关心这份报告中的几个。
  • 字段为:“id”、“intWorkOrderID”、“intOrder”、“dblTimeSpentHours”、“strDescription”、“intAssignedToUserID”、“dtmDateCompleted”、“intCompletedByUserID”

标签: sql select group-by jasper-reports derby


【解决方案1】:

您正在选择 tblWorkOrderTask 表中的所有列。 “id”列是该表中的第一列。您收到错误消息,因为您没有在选择列表中指定所有列。

此选择会起作用,但我不确定您需要从表中获取哪些信息。

SELECT id, intworkorderid
FROM tblWorkOrderTask 
group by id, intworkorderid

http://www.w3schools.com/sql/sql_groupby.asp

【讨论】:

  • 所以,如果我理解正确的话,为了使用 group by,您需要在选择行中具体说明吗?如果需要,我需要单独选择所有字段吗?另外,为什么在group by中使用ID?我是否需要始终按第一列分组?即使所有记录都有唯一的价值?
  • 我正在使用您提供的所有信息,但您必须将每个非聚合列中的 select 包含在 group by 中。您的分组依据可以比您选择的列多,但不能少。
  • 好的,所以我尝试了这个:从“tblWorkOrderTask”中选择“id”、“intWorkOrderID”,其中“dblTimeSpentHours”>0 和“dtmDateCompleted”在 $P{DATE_FROM} 和 $P{DATE_TO} 组之间by "id", "intWorkOrderID" 正如你所说,group by 包含选择列表中完全相同的列。但是我现在得到:错误填充打印...未知列名:intOrder net.sf.jasperreports.engine.JRException:未知列名:intOrder 该列是第三列,在workorderid 列之后。它不在我的选择列表中,在我的代码/报告中也没有。那么它为什么在乎呢?
  • 列名见上文
  • 另外,一个有趣的注释...我尝试了你的建议,我得到了一个表不存在错误。所以我将所有内容都用引号括起来,现在我在 intOrder 上得到名称未知列错误(就像上面一样)
【解决方案2】:

去掉 GROUP BY 子句——如果你只是想对结果进行排序,那么请改用 ORDER BY;但除此之外,你也不需要。

编辑

正如错误所说,您的 SELECT 列表中的所有内容都必须是以下两种情况之一 - 1) 也列在您的 GROUP BY 列表中,或者 2) 聚合值。这是一个可行的示例:

SELECT intworkorderid, COUNT(*) 
FROM   "tblworkordertask" 
WHERE  "dbltimespenthours" > 0 
       AND "dtmdatecompleted" BETWEEN $P{DATE_FROM} AND $P{DATE_TO}
GROUP  BY "intworkorderid" 

【讨论】:

  • 不,对不起...我不在乎它是否已订购,我只想按工单号对结果进行分组。工单有多个任务,CMMS 将每个任务存储为一个记录,因此有多个记录,每个记录都具有相同的工单编号。我只想知道有多少个独特的工单完成了 timespent 字段。
  • @KevinSadowy——你没有抓住重点。 ORDER BY 对您的结果进行分组。由于您没有使用聚合,也没有使用HAVING 过滤器,因此您不需要GROUP BYGROUP BY 有特殊要求——如果你要使用它,你必须遵守它的规则(即,在 SELECT 中列出所有字段,然后在 GROUP BY 中再次列出它们)。无论哪种方式都可以,但您不能将它与SELECT * 结合使用——这就是错误告诉您的内容。
  • @KevinSadowy -- 查看更新示例,说明错误告诉您什么/如何满足要求。
  • 好的。我尝试了您的示例,添加了大写和引号。我得到了未知的列:ID 错误。我尝试将其更改为 ORDER BY,然后我收到一条消息,说如果选择具有聚合,那么所有条目都必须是有效的聚合。所以我删除了 COUNT (*),再次得到未知列:ID 错误。所以,我将选择更改为 SELECT *,现在我得到了我所期望的:相同工作订单 ID 的多个条目,但按数字顺序。
  • @KevinSadowy -- 无效列错误意味着您在 SELECT 中使用了在表中找不到的列名(可能是“ID”)。至于聚合函数 (COUNT(*)),如果你使用它,那么你必须使用 GROUP BY。很抱歉让您感到沮丧——这是基本的 SQL——这里有一个快速入门/参考可以帮助你更好地理解它:w3schools.com/sql/sql_groupby.asp
【解决方案3】:

是的 - 要使用分组依据,您需要在选择行中具体说明。

首先,决定要显示哪些字段。如果您想要它们全部,则将它们全部包含在内。

添加 COUNT() 函数以获取所选字段的计数后,您将需要添加 GROUP BY 子句。 COUNT() 是一个 AGGREGATE 函数,类似于 SUM() 和 AVG()。

在 GROUP BY 子句中指定这么多字段有点违反直觉,有点痛苦,但这是必要的。 FIRST GROUP BY 字段是最重要的,因为这通常是您所关心的。 第一个字段可以是任何 SELECTed 字段,但不一定是第一个。

在 GROUP BY 中包含不是 COUNT() 等 AGGREGATE 函数的每个字段。

另外,如果您尝试对一组订单进行计数,您可能不需要或不需要 SELECT 中的所有字段。 您可能只想指定对工作订单 ID 唯一的字段。

示例:如果您想获取这些字段的 COUNT,您将指定除 COUNT() 之外的所有 SELECTED 字段。

SELECT
    intWorkOrderID,
    COUNT(id),
    strDescription
FROM   tblworkordertask
WHERE  dbltimespenthours > 0 
       AND dtmdatecompleted BETWEEN $P{DATE_FROM} AND $P{DATE_TO}
GROUP BY
    intworkorderid,
    strDescription

【讨论】:

    猜你喜欢
    • 2021-08-26
    • 1970-01-01
    • 2021-03-17
    • 1970-01-01
    • 1970-01-01
    • 2013-09-27
    • 2021-12-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多