【问题标题】:Distinctly sum a column on a joined table?对连接表上的列进行明确求和?
【发布时间】:2012-11-01 19:04:16
【问题描述】:

这是一个简单的问题,我不确定这里是否可行。问题来了:

=> http://sqlfiddle.com/#!12/584f1/7

解释:

  • 票属于与会者
  • 与会者有收入
  • 我需要按部分对门票进行分组并获得总收入。
  • 这会重复计算与会者,因为 2 张门票可以属于同一与会者,因此会重复计算。我想获取收入的总和,但只计算参加者一次。

在我的 sqlfiddle 示例中,我想看看:

section | total_revenue
------------------------
A       | 40            <= 40 is correct, but I'm getting 50...
B       | null
C       | 40

我想在不使用子查询的情况下解决这个问题。我需要一个可扩展的解决方案,它允许我在单个查询中对不同连接上的多个列执行此操作。所以无论我做什么,我都愿意接受建议。

感谢您的帮助。

【问题讨论】:

  • 它已经为我工作了......
  • 我将此标记为重复,但仔细检查后发现并非如此。它密切相关,但与the previous question 不同。不要关闭它。
  • 您似乎误以为子查询天生就较慢或不可扩展。事实并非如此。在 SELECT 列表中使用子查询可能需要您对每个值重复它,这并不理想 - 但FROM 或 CTE 中的子查询可能是解决代码和性能方面问题的最有效方法。因此,我建议您将该要求削弱为“不在 SELECT 列表中使用子查询”。

标签: sql postgresql distinct aggregate-functions


【解决方案1】:

这是一个使用row_number()的版本:

select section,
  sum(revenue) Total
from 
(
  select t.section, a.revenue,
    row_number() over(partition by a.id, t.section order by a.id) rn
  from tickets t
  left join attendees a
    on t.attendee_id = a.id
) src
where rn = 1
group by section
order by section;

SQL Fiddle with Demo

【讨论】:

  • "不使用子查询"
  • @RichardTheKiwi 我知道这个要求,我正在展示一个带有row_number() 的版本,以展示在他们想要包含其他字段的情况下如何实现它。
  • @RichardTheKiwi 基于这个问题,我怀疑意图真的是在 SELECT 列表中没有子查询,因为希望避免对每个值重复子查询。
【解决方案2】:

同样,没有子查询

关键元素是将PARTITION BY添加到窗口函数:

SELECT DISTINCT
       t.section
--    ,sum(count(*))       OVER (PARTITION BY t.section) AS tickets_count
      ,sum(min(a.revenue)) OVER (PARTITION BY t.section) AS atendees_revenue
FROM   tickets t
LEFT   JOIN attendees a ON a.id = t.attendee_id
GROUP  BY t.attendee_id, t.section
ORDER  BY t.section;

-> sqlfiddle

在这里,您 GROUP BY t.attendee_id, t.section,在您通过窗口函数运行结果之前。并在窗口函数中使用PARTITION BY t.section,因为您希望这次按部分分区结果。

如果您也想获得票数,请取消注释第二行。

否则,它的工作方式类似于my answer to your previous question。即,其余的解释都适用。

【讨论】:

    【解决方案3】:

    你可以这样做:

    select t.section, sum(d.revenue)
    from 
    (
      SELECT DISTINCT section, attendee_id FROM tickets
    ) t
    left join attendees d on t.attendee_id = d.id
    group by t.section
    order by t.section;
    

    【讨论】:

    • “不使用子查询”。那,以及无论如何都怀疑表结构是错误的。我猜收入是每个与会者的总发票价值,即与会者购买了多少票......
    猜你喜欢
    • 2022-11-12
    • 1970-01-01
    • 1970-01-01
    • 2021-10-09
    • 1970-01-01
    • 1970-01-01
    • 2012-10-04
    • 2021-07-30
    • 2018-03-29
    相关资源
    最近更新 更多