明确地将联合表上的列相加?

时间:2012-11-01 19:04:16

标签: sql postgresql distinct aggregate-functions

这是一个简单的问题,我不确定它是否可行。这是问题所在:

=> 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

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

感谢您的帮助。

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

同样,没有子查询

关键元素是将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类似。即,其余解释适用。

答案 2 :(得分:0)

你可以这样做:

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;