为什么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”的列,但无法从查询的这一部分引用该列。
您使用的是“表表达式”。表表达式(如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
除了现有的答案之外,您当然可以使用派生表使用原始查询,只需将隐式连接更改为显式连接:
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;
请检查我下面的代码,我已经用正确的解释标记了这个问题。
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 查询2
问题内容: 假设您具有以下一对多关系:。现在,您要选择所有学生名为“ 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关键字的连接。届时该表