JOIN的ON子句中的Aggregare函数

时间:2019-02-15 14:31:33

标签: sql postgresql

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

&amp

错误:“ min_price”列不存在 第19行:AND价格=最低价格                               ^ 提示:表“ h1”中有一个名为“ min_price”的列,但无法在查询的此部分中引用。

3 个答案:

答案 0 :(得分:1)

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

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; 

答案 1 :(得分:1)

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

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; 

答案 2 :(得分:0)

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

如果您想h2使用h1,请使用公用表表达式(简称CTE)。您的查询可以改写为:

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