【问题标题】:aggregate functions are not allowed in WHEREWHERE 中不允许使用聚合函数
【发布时间】:2017-06-16 16:36:31
【问题描述】:

我正在使用此查询来使用 postgresql 按最新日期查找唯一记录。我遇到的错误是“WHERE 中不允许使用聚合函数”。 How to fix error “aggregate functions are not allowed in WHERE” 在此链接之后,我尝试使用内部选择功能。但这没有用。请帮我编辑查询。我正在使用 PgAdmin III 作为客户端。

SELECT Distinct t1.pa_serial_
    ,t1.homeownerm_name
    ,t1.districtvdc
    ,t1.date as firstrancheinspection_date
    ,t1.status
    ,t1.name_of_data_collector
    ,t1.fulcrum_id
    ,first_tranche_inspection_v2_reporting_questionnaire.date_reporting
From first_tranche_inspection_v2 t1
LEFT JOIN first_tranche_inspection_v2_reporting_questionnaire ON (t1.fulcrum_id = first_tranche_inspection_v2_reporting_questionnaire.fulcrum_parent_id)
where first_tranche_inspection_v2_reporting_questionnaire.date_reporting = (
        select Max(first_tranche_inspection_v2_reporting_questionnaire.date_reporting)
        from first_tranche_inspection_v2
        where first_tranche_inspection_v2.pa_serial_ = t1.pa_serial_
        );

【问题讨论】:

  • 在您的子查询中,您从 first_tranche_inspection_v2 中进行选择,但 MAX 函数与 first_tranche_inspection_v2_reporting_questionnaire 中的字段相关。这是一个错字吗?或者你想在那里实现什么?
  • 是的,这是我的要求,所以我加入了这两个表
  • 不,我的意思是 MAX 用于聚合相关表,因此您使用 MAX 的字段必须是该表的字段。事实并非如此,您没有在子查询中聚合表,而只是参考您必须在它之外确定的最大值。但是在子查询之外没有聚合。简而言之:你在这里做错了什么。问题是:你想做什么?
  • 我想做的是 - pa_serial_、homeownerm_name、status..etc 等信息是从 first_tranche_inspection_v2 获得的,但其他几列是从 first_tranche_inspection_v2_reporting_questionnaire 获得的,我想根据 date_reporting 获取最新记录来自 first_tranche_inspection_v2_reporting_questionnaire 表,因为该表包含不同日期的相同信息,我需要获取唯一的最新记录
  • 展示样本数据。

标签: sql postgresql


【解决方案1】:

DISTINCT 通常最终在许多 RDBMS 中使用 GROUP BY 查询来实现。我认为在您当前的查询中发生的情况是,已经有一个隐式聚合涉及您的 SELECT 中的列。因此,涉及MAX() 的相关子查询实际上是一个聚合,因为DISTINCT

一种快速的解决方法可能是在没有DISTINCT 的情况下执行原始查询,然后对结果集进行子查询以仅保留不同的记录:

WITH cte AS (
    SELECT t1.pa_serial_,
           t1.homeownerm_name,
           t1.districtvdc,
           t1.date as firstrancheinspection_date,
           t1.status,
           t1.name_of_data_collector,
           t1.fulcrum_id,
           t2.date_reporting
    FROM first_tranche_inspection_v2 t1
    LEFT JOIN first_tranche_inspection_v2_reporting_questionnaire t2
        ON t1.fulcrum_id = t2.fulcrum_parent_id
    WHERE t2.date_reporting = (SELECT MAX(t.date_reporting)
                               FROM first_tranche_inspection_v2 t
                               WHERE t.pa_serial_ = t1.pa_serial_)
);

SELECT DISTINCT t.pa_serial_,
                t.homeownerm_name,
                t.districtvdc,
                t.firstrancheinspection_date,
                t.status,
                t.name_of_data_collector,
                t.fulcrum_id,
                t.date_reporting
FROM cte t

请注意,我继续为您的联接中的第二个表添加了一个别名,这使查询更易于阅读。

【讨论】:

  • 我收到此错误“错误:t.date_reporting 列不存在第 13 行:WHERE t2.date_reporting = (SELECT MAX(t.date_reporting)”。实际上,date_reporting 来自辅助表“first_tranche_inspection_v2_reporting_questionnaire”和 irst_tranche_inspection_v2 是我的主表。
  • 这毫无意义。此时,您应该使用示例数据更新您的问题,并希望输出清晰。
  • “错误:缺少表“first_tranche_inspection_v2_reporting_questionnaire”第 3 行的 FROM 子句条目:Max(first_tranche_inspection_v2_reporting_questionnaire)”
  • 再一次,您尝试做的事情毫无意义。
  • 我想做的是从 first_tranche_inspection_v2 获得诸如 pa_serial_、homeownerm_name、status..etc 之类的信息,从 first_tranche_inspection_v2_reporting_questionnaire 获得其他几列,我想根据 date_reporting 从first_tranche_inspection_v2_reporting_questionnaire 表
【解决方案2】:

您希望在每次检查时加入最新的报告问卷。在 PostgreSQL 中,您可以为此使用 DISTINCT ON

select fti.*, rq.* 
from first_tranche_inspection_v2 fti
left join
(
  select distinct on (fulcrum_parent_id) *
  from first_tranche_inspection_v2_reporting_questionnaire
  order by fulcrum_parent_id, date_reporting desc
) rq on rq.fulcrum_parent_id = fti.fulcrum_id;

或者使用标准 SQL 的ROW_NUMBER:

select fti.*, rq.* 
from first_tranche_inspection_v2 fti
left join
(
  select 
    ftirq.*, 
    row_number() over (partition by fulcrum_parent_id order by date_reporting desc) as rn
  from first_tranche_inspection_v2_reporting_questionnaire ftirq
) rq on rq.fulcrum_parent_id = fti.fulcrum_id and rq.rn = 1;

你想要做的应该是这样的:

select fti.*, rq.* 
from first_tranche_inspection_v2 fti
left join first_tranche_inspection_v2_reporting_questionnaire rq
  on rq.fulcrum_parent_id = fti.fulcrum_id
  and (rq.fulcrum_parent_id, rq.date_reporting) in
  (
    select fulcrum_parent_id, max(date_reporting)
    from first_tranche_inspection_v2_reporting_questionnaire
    group by fulcrum_parent_id
  );

这也有效,唯一的缺点是您将表格first_tranche_inspection_v2_reporting_questionnaire 读了两次。

【讨论】:

  • 我正在使用第一个...这很有魅力..谢谢
  • 如果我需要在单个记录的同一查询中计算 rq.fulcrum_parent_id = fti.fulcrum_id 的记录数怎么办?
  • 我认为您在此处编写的第三个查询对执行此操作很有用。我现在还需要的是 first_tranche_inspection_v2 的 fulcrum_id 中与 first_tranche_inspection_v2_reporting_questionnaire 的 fulcrum_parent_id 匹配的唯一记录的记录数?请帮忙
  • select fti.*, rq.* ,count from first_tranche_inspection_v2 fti left join first_tranche_inspection_v2_reporting_questionnaire rq on rq.fulcrum_parent_id = fti.fulcrum_id and (rq.fulcrum_parent_id, rq.date_reporting) in (select count(fulcrum_parent_id)作为计数,来自 first_tranche_inspection_v2_reporting_questionnaire 组的 fulcrum_parent_id,max(date_reporting) 由 fulcrum_parent_id );
  • 我正在尝试上面的代码,但它说子查询的列太多。
猜你喜欢
  • 2017-07-17
  • 1970-01-01
  • 2014-01-26
  • 1970-01-01
  • 1970-01-01
  • 2019-02-21
  • 2015-03-04
  • 2021-07-29
  • 1970-01-01
相关资源
最近更新 更多