【问题标题】:How to aggregate based on other rows that share a key?如何基于共享键的其他行进行聚合?
【发布时间】:2021-09-19 20:11:53
【问题描述】:

我有一个格式如下的表格:

我觉得这应该很简单,但我正在努力想出一个高性能查询,该查询可以使用共享键基于其他行执行聚合。例如,我想对具有键 MediaLength 的用户的行求和,但前提是共享 event_id 的键为 Score 的行大于或等于 3。

简单求和的结果:

SELECT SUM(value::float) FROM data WHERE key = 'MediaLength' AND user_id = '9765f312-0d0b-4db0-b4c5-217eec81d7c3'

Result: 40

我想在这里实现的结果是15。在上表中,您可以看到行是事件的子项。我只想总结value 列,其中key = 'MediaLength' 及其姊妹行与key = 'Score' 具有value >= 3

这是我迄今为止尝试过的查询,但它似乎有点混乱,并且由于 more than one row returned by subquery 错误也不起作用:

select
    sum(value::float)
        filter (where (
            select d.value::float
            from data d
            where d.event_id = event_id
            and d.key = 'Score'
        ) >= 3)
from data
where user_id = '9765f312-0d0b-4db0-b4c5-217eec81d7c3'

这是一个简单的示例,但将来我还需要过滤可能的多个其他键,因此非常感谢任何有关如何扩展的建议。

【问题讨论】:

  • 我认为您需要限定d.event_id = event_id 的范围以明确使用外部表的别名(d.event_id = outer.event_id),否则普通的event_id 将引用内部data d 关系为好吧。
  • 请提供表格定义和一些示例数据作为文本,而不是屏幕截图(不鼓励数据!)。理想情况下,添加一个小提琴。随机示例:dbfiddle.uk/…
  • 我冒昧地改进了描述。如果我说的不对,请纠正我。
  • 谢谢欧文!是的,澄清是完美的:)

标签: sql postgresql relational-division


【解决方案1】:

我只想对 key = 'MediaLength' 的 value 列及其 key = 'Score' 的姊妹行的值 >= 3 求和。

SELECT sum(value::float)  -- why the cast?
FROM   data d
WHERE  user_id = '9765f312-0d0b-4db0-b4c5-217eec81d7c3'
AND    key = 'MediaLength'
AND    EXISTS (
   SELECT FROM data ds
   WHERE  ds.event_id = d.event_id
   AND    ds.user_id = d.user_id    -- !
   AND    ds.key = 'Score'
   AND    ds.value >= 3
   );

在这里,如果 any 姐妹通过了过滤器,则带有 key = 'MediaLength' 的行符合条件。 (可能还有更多的姐妹没有通过测试。)

如果只能有一个 单个 符合条件的姊妹行(由唯一约束/索引强制执行?),那么自连接会更简单一些:

SELECT sum(value::float)
FROM   data d
JOIN   data ds USING (event_id, user_id)
WHERE  d.user_id = '9765f312-0d0b-4db0-b4c5-217eec81d7c3'
AND    d.key = 'MediaLength'
AND    ds.key = 'Score'
AND    ds.value >= 3;

自联接将为多个符合条件的姊妹行生成多个结果行。

在其核心,这可以转换为 问题。特别是,因为...

将来我还需要过滤潜在的多个其他键

见:

【讨论】:

  • 您好 Erwin,感谢您提供如此详细的回复!您能否对自联接进行一些扩展,为什么这不适用于过滤多个姊妹行?
  • @Ollie:第二个查询中的连接会为多个符合条件的姊妹行生成多个结果行,而第一个查询不会像这样将行相乘。
  • 啊,是的,经过一些测试,我现在看到了,再次感谢!如果我可以大胆地再问一个问题:您是否碰巧知道第一个查询的性能影响?长话短说,对于当前超过 1000 万行的数据集,我们将进行大量聚合。
  • @Ollie:对于手头的查询,我希望第一个查询是最快的选择。适当的索引来支持它对于大表来说是必不可少的。
猜你喜欢
  • 2022-07-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-26
  • 2019-02-18
  • 2020-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多