我有以下查询:(这里是示例模式:https://www.db-fiddle.com/f/5e9gvc6oridjywigpwrkm/3)
SELECT
t.customer_id
, t.ticket_id
, c.combination_id
, c.possible_prize + c.confirmed_prize + coalesce(cb.bonus_amount,0) AS won_amount
, round(mul(o.value)::numeric,3) AS odds
FROM tickets t
JOIN combinations c ON c.ticket_id = t.ticket_id
LEFT JOIN combination_bonus cb ON cb.combination_id = c.combination_id
JOIN outcomes o ON o.ticket_id = t.ticket_id AND o.outcome_id = ANY(c.outcomes)
GROUP BY 1,2,3, cb.bonus_amount
ORDER BY 1
没有 + coalesce(cb.bonus_amount,0)
它运行良好,为什么只有这列需要分组,而不是这个等式中的其他两列?
另外,如果我把这一行放到sum()中,结果将是完全错误的,因为它将被乘以几倍,我不知道为什么和如何得到它。
如果您能对这两种情况作出解释,我将不胜感激。
2条答案
按热度按时间dldeef671#
如果没有+coalesce(cb.bonus\u amount,0),它运行良好,为什么只需要将此列分组,而不需要将此等式中的其他两列分组?
当涉及到列时
c.possible_prize
以及c.confirmed_prize
:您不需要这些group by
子句,因为该子句已包含c.combination_id
(隐藏在位置参数后面)3
),它是表的主键c
.postgres是少数几个正确实现函数依赖列概念的数据库之一(不是唯一一个):一旦将表的主键放入
group by
子句中,您不需要添加同一表的其他列:主键唯一地标识一行。另一方面,您没有表的主键
cb
在group by
条款。你会争辩说你带了一张tablecb
精确地使用该列上的连接条件,以某种方式保证唯一性:嗯,博士后可能没那么聪明。如果将查询放在那里,它应该可以正常工作,因此:
xwmevbvl2#
这是一个有点长的评论。
sql允许——和postgres支持——使用
group by
然后选择其他列而不使用聚合。这称为函数依赖(其他列在功能上依赖于unique/主键)。如果您的第一个查询工作正常,那么它将在postgres中使用此功能——基于
combinations.combination_id
作为主键(或者至少是唯一的)。然而,combination_bonus
车里没有钥匙group by
. 即使combination_bonus.combination_id
是主键,postgres可能不够聪明,无法将这些信息用于功能依赖。所以,只需包含整个表达式
coalesce(cb.bonus_amount, 0)
在group by
. 或者使用聚合函数。