不同行的MYSQL sum()

时间:2010-03-12 22:20:57

标签: mysql sum

我在SQL查询中使用sum()寻求帮助:

SELECT links.id, 
       count(DISTINCT stats.id) as clicks, 
       count(DISTINCT conversions.id) as conversions, 
       sum(conversions.value) as conversion_value 
FROM links 
LEFT OUTER JOIN stats ON links.id = stats.parent_id 
LEFT OUTER JOIN conversions ON links.id = conversions.link_id 
GROUP BY links.id 
ORDER BY links.created desc;

我使用DISTINCT,因为我正在“分组”,这可以确保同一行不会被计算多次。

问题是SUM(conversions.value)多次计算每行的“值”(由于分组依据)

我基本上希望为每个DISTINCT conversions.id执行SUM(conversions.value)

这可能吗?

8 个答案:

答案 0 :(得分:69)

我可能错了但是从我的理解

  • conversions.id 是表转化
  • 主键
  • stats.id 是表统计信息
  • 主键

因此,对于每次转换。您最多只有一个链接。受影响。

你的请求有点像做2套笛卡尔积:

[clicks]
SELECT *
FROM links 
LEFT OUTER JOIN stats ON links.id = stats.parent_id 

[conversions]
SELECT *
FROM links 
LEFT OUTER JOIN conversions ON links.id = conversions.link_id 

并为每个链接获得sizeof([clicks])x sizeof([conversions])行

如您所知,您的请求中的唯一转化次数可以通过

获得
count(distinct conversions.id) = sizeof([conversions])

此独特设法删除笛卡尔积中的所有[点击]行

但显然

sum(conversions.value) = sum([conversions].value) * sizeof([clicks])

在你的情况下,因为

count(*) = sizeof([clicks]) x sizeof([conversions])
count(*) = sizeof([clicks]) x count(distinct conversions.id)

你有

sizeof([clicks]) = count(*)/count(distinct conversions.id)

所以我会用

测试你的请求
SELECT links.id, 
   count(DISTINCT stats.id) as clicks, 
   count(DISTINCT conversions.id) as conversions, 
   sum(conversions.value)*count(DISTINCT conversions.id)/count(*) as conversion_value 
FROM links 
LEFT OUTER JOIN stats ON links.id = stats.parent_id 
LEFT OUTER JOIN conversions ON links.id = conversions.link_id 
GROUP BY links.id 
ORDER BY links.created desc;

让我发布! 杰罗姆

答案 1 :(得分:10)

Jeromes解决方案实际上是错误的,可能会产生错误的结果!!

sum(conversions.value)*count(DISTINCT conversions.id)/count(*) as conversion_value

让我们假设下表

conversions
id value
1 5
1 5
1 5
2 2
3 1

不同ID的正确值总和为8。 杰罗姆的公式产生:

sum(conversions.value) = 18
count(distinct conversions.id) = 3
count(*) = 5
18*3/5 = 9.6 != 8

答案 2 :(得分:7)

有关您看到错误号码的原因的解释, read this

我认为Jerome可以处理导致错误的原因。 Bryson的查询可行,但在SELECT中使用子查询可能效率低下。

答案 3 :(得分:4)

使用以下查询:

SELECT links.id
  , (
    SELECT COUNT(*)
    FROM stats
    WHERE links.id = stats.parent_id
  ) AS clicks
  , conversions.conversions
  , conversions.conversion_value
FROM links
LEFT JOIN (
  SELECT link_id
    , COUNT(id) AS conversions
    , SUM(conversions.value) AS conversion_value
  FROM conversions
  GROUP BY link_id
) AS conversions ON links.id = conversions.link_id
ORDER BY links.created DESC

答案 4 :(得分:3)

我使用子查询来执行此操作。它消除了分组问题。 因此查询将类似于:

SELECT COUNT(DISTINCT conversions.id)
...
     (SELECT SUM(conversions.value) FROM ....) AS Vals

答案 5 :(得分:2)

这样的事情怎么样:

select l.id, count(s.id) clicks, count(c.id) clicks, sum(c.value) conversion_value
from    (SELECT l.id id, l.created created,
               s.id clicks,  
               c.id conversions,  
               max(c.value) conversion_value                    
        FROM links l LEFT
        JOIN stats s ON l.id = s.parent_id LEFT
        JOIN conversions c ON l.id = c.link_id  
        GROUP BY l.id, l.created, s.id, c.id) t
order by t.created  

答案 6 :(得分:1)

这样就可以了,只需将会话ID除以重复的会话ID计数。

SELECT a.id,
       a.clicks,
       SUM(a.conversion_value/a.conversions) AS conversion_value,
       a.conversions
FROM (SELECT links.id, 
       COUNT(DISTINCT stats.id) AS clicks, 
       COUNT(conversions.id) AS conversions, 
       SUM(conversions.value) AS conversion_value 
      FROM links 
      LEFT OUTER JOIN stats ON links.id = stats.parent_id 
      LEFT OUTER JOIN conversions ON links.id = conversions.link_id 
      GROUP BY conversions.id,links.id
      ORDER BY links.created DESC) AS a
GROUP BY a.id

答案 7 :(得分:0)

Select sum(x.value) as conversion_value,count(x.clicks),count(x.conversions)
FROM
(SELECT links.id, 
       count(DISTINCT stats.id) as clicks, 
       count(DISTINCT conversions.id) as conversions,
       conversions.value,       
FROM links 
LEFT OUTER JOIN stats ON links.id = stats.parent_id 
LEFT OUTER JOIN conversions ON links.id = conversions.link_id 
GROUP BY conversions.id) x
GROUP BY x.id 
ORDER BY x.created desc;

我相信这会给您所需的答案。