sql—为什么在特定列上强制使用group by,而在其他列上不强制使用group by

hxzsmxv2  于 2021-07-29  发布在  Java
关注(0)|答案(2)|浏览(309)

我有以下查询:(这里是示例模式: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()中,结果将是完全错误的,因为它将被乘以几倍,我不知道为什么和如何得到它。
如果您能对这两种情况作出解释,我将不胜感激。

dldeef67

dldeef671#

如果没有+coalesce(cb.bonus\u amount,0),它运行良好,为什么只需要将此列分组,而不需要将此等式中的其他两列分组?
当涉及到列时 c.possible_prize 以及 c.confirmed_prize :您不需要这些 group by 子句,因为该子句已包含 c.combination_id (隐藏在位置参数后面) 3 ),它是表的主键 c .
postgres是少数几个正确实现函数依赖列概念的数据库之一(不是唯一一个):一旦将表的主键放入 group by 子句中,您不需要添加同一表的其他列:主键唯一地标识一行。
另一方面,您没有表的主键 cbgroup by 条款。你会争辩说你带了一张table cb 精确地使用该列上的连接条件,以某种方式保证唯一性:

LEFT JOIN combination_bonus cb ON cb.combination_id = c.combin

嗯,博士后可能没那么聪明。如果将查询放在那里,它应该可以正常工作,因此:

GROUP BY 1,2,3, cb.combination_id
xwmevbvl

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 . 或者使用聚合函数。

相关问题