当前位置: 首页 > 知识库问答 >
问题:

连接中ON子句中的Aggregare函数

姜博
2023-03-14

为什么Postgres不允许我在JOIN中使用聚合函数?

SELECT p.id, p.actual_price,
   h1.min_price, h1.max_price 
FROM (
  SELECT min(price) as min_price, max(price) as max_price, product_id
  FROM prices_history 
  WHERE timestamp > '2019-01-01'
  GROUP BY product_id
  ) AS h1,
  products p
JOIN (
  SELECT max(timestamp), price, product_id
  FROM prices_history 
  WHERE timestamp > '2019-01-01'
  GROUP BY product_id, price
  ) AS h2
  ON  h2.product_id = p.id 
     AND h2.price = h1.min_price
 WHERE 
  p.id = h1.product_id
 GROUP BY p.id, p.actual_price, h1.min_price, h2.max_price
 ORDER BY p.id;

错误:列“min_price”不存在第19行:且price=min_price^提示:表“h1”中有一个名为“min_price”的列,但无法从查询的这一部分引用该列。

共有3个答案

孙永思
2023-03-14

您使用的是“表表达式”。表表达式(如h2)不能引用前一个表达式(如h1)或其列,除非在JOIN子句中。

如果您想使用h2来使用h1,请使用公共表表达式(简称CTEs)。您的查询可以重新措辞为:

with
h1 as (
  SELECT min(price) as min_price, max(price) as max_price, product_id
  FROM prices_history 
  WHERE timestamp > '2019-01-01'
  GROUP BY product_id
),
h2 as (
  SELECT max(timestamp), price, product_id
  FROM prices_history 
  WHERE timestamp > '2019-01-01'
  GROUP BY product_id, price
  )
SELECT p.id,
  p.actual_price,
  h1.min_price, h1.max_price 
from products p
join h2 ON p.id = h2.product_id
join h1 on h2.price = h1.min_price
       and p.id = h1.product_id
GROUP BY p.id, h1.min_price, h1.max_price, p.actual_price
ORDER BY p.id
夹谷星剑
2023-03-14

除了现有的答案之外,您当然可以使用派生表使用原始查询,只需将隐式连接更改为显式连接:

SELECT p.id, p.actual_price,
   h1.min_price, h1.max_price 
FROM (
  SELECT min(price) as min_price, max(price) as max_price, product_id
  FROM prices_history 
  WHERE timestamp > '2019-01-01'
  GROUP BY product_id
  ) AS h1
JOIN
  products p
ON p.id = h1.product_id
JOIN (
  SELECT max(timestamp), price, product_id
  FROM prices_history 
  WHERE timestamp > '2019-01-01'
  GROUP BY product_id, price
  ) AS h2
  ON  h2.product_id = p.id 
     AND h2.price = h1.min_price
 GROUP BY p.id, p.actual_price, h1.min_price, h2.max_price
 ORDER BY p.id; 
松成和
2023-03-14

请检查我下面的代码,我已经用正确的解释标记了这个问题。

SELECT p.id, 
       p.actual_price, 
       min_price, 
       max_price 
FROM   (SELECT Min(price) AS min_price, 
               Max(price) AS max_price, 
               product_id 
        FROM   prices_history 
        WHERE  timestamp > '2019-01-01' 
        GROUP  BY product_id) AS h1, 
       products p ,
       join (SELECT Max(timestamp), 
                    price, 
                    product_id 
             FROM   prices_history 
             WHERE  timestamp > '2019-01-01' 
             GROUP  BY product_id, 
                       price) AS h2 
         ON p.id = h2.product_id 
            AND price = min_price  -- <= This join is same level with subquery h1.
                                   -- you cannot use min_price here
WHERE  p.id = h1.product_id 
GROUP  BY p.id, 
          min_price, 
          max_price, 
          p.actual_price 
ORDER  BY p.id; 

为了解决这个问题,我还用正确的内部连接替换了遗留的逗号分隔连接

with h1 as 
(
    SELECT Min(price) AS min_price, 
           Max(price) AS max_price, 
           product_id 
    FROM   prices_history 
    WHERE  timestamp > '2019-01-01' 
    GROUP  BY product_id

), h2 as 
(
    SELECT Max(timestamp), 
            price, 
            product_id 
     FROM   prices_history 
     WHERE  timestamp > '2019-01-01' 
     GROUP  BY product_id, 
               price

)
SELECT p.id, 
       p.actual_price, 
       min_price, 
       max_price 
FROM  h1, 
inner join products p  
  on p.id = h1.product_id 
    join  h2 
      ON p.id = h2.product_id 
         AND price = min_price   
GROUP  BY p.id, 
          min_price, 
          max_price, 
          p.actual_price 
ORDER  BY p.id; 
 类似资料:
  • 问题内容: 假设您具有以下一对多关系:。现在,您要选择所有学生名为“ John”且其科学工作称为“Black Holes”的学校。 我这样做如下,但是由于某种原因,它使我无法接受所有可能的学校。 更新资料 找到此答案后,我尝试了以下操作,但结果相同(它使我返回所有学校而不是所有学校): 问题答案: public static Specification spec() { return (root,

  • 问题内容: 我正在尝试将相当短的SQL转换为sqlAlchemy ORM查询。SQL使用Postgres来创建一组日期,而我的目标是创建一组按列之一分类的时间序列数组。 这些表(简化后)非常简单: 我需要的输出是每个地方的时间序列,包括当一天未报告计数时的空值。例如,这将对应于四天的系列: 我可以很容易地做到这一点,方法是确定一个日期范围和地点,并将其与计数结合起来: 我似乎无法弄清楚的是如何让S

  • 问题内容: 我今天输入了错误的查询,但它仍然有效,并给出了预期的结果。我的意思是运行此查询: 但是我不小心跑了这个查询 (请注意,而不是最后一个子句中的) 并且都从用户ID返回了正确的员工ID。 这两个查询有什么区别?第二种形式是否仅联接满足条件的2个表的成员,而第一种形式将联接整个表,然后运行查询?一个效率比另一个效率高吗?还有其他我想念的东西吗? 谢谢! 问题答案: 对于这样的内部联接,它们在

  • 问题内容: 我正在尝试在子句中构建case / if语句。 问题在于该列包含文本和数字。我要与之比较的列是一个整数。 有没有一种方法可以检测列是否包含字符或数字,然后将其设置为0,然后将其设置为0? 这是一个伪查询可以帮助您: 问题答案: 您正在寻找IsNumeric,但它并不总是有效(+,-和。是数字),因此您需要使用GBN所描述的解决方案,即在您的varchar中添加.0e0

  • 问题内容: 我有以下MySQL查询: 我收到此错误: #1054-‘on子句’中的未知列’p.id’ 据我所知,查询看起来是正确的,知道发生什么了吗? 问题答案: 不要混合使用ANSI-89样式和ANSI-92样式的连接。它们具有不同的优先级,这可能导致混乱的错误,这就是这里发生的情况。您的查询的解释如下: 在上面的示例中,在甚至考虑了逗号样式的连接之前,首先评估使用JOIN关键字的连接。届时该表