在mysql中进行一些计算,使用GROUP BY时关闭数字

时间:2011-05-27 16:05:17

标签: mysql group-by

我正在运行以下查询以获取用户的统计信息,具体取决于我支付的费用。

SELECT hit_paylevel, sum(hit_uniques) as day_unique_hits
       , (sum(hit_uniques)/1000)*hit_paylevel as day_earnings
       , hit_date 
FROM daily_hits 
WHERE hit_user = 'xxx' AND hit_date >= '2011-05-01' AND hit_date < '2011-06-01' 
GROUP BY hit_user

有问题的表格如下:

CREATE TABLE IF NOT EXISTS `daily_hits` (
  `hit_itemid` varchar(255) NOT NULL,
  `hit_mainid` int(11) NOT NULL,
  `hit_user` int(11) NOT NULL,
  `hit_date` date NOT NULL,
  `hit_hits` int(11) NOT NULL DEFAULT '0',
  `hit_uniques` int(11) NOT NULL,
  `hit_embed` int(11) NOT NULL,
  `hit_paylevel` int(1) NOT NULL DEFAULT '1',
  PRIMARY KEY (`hit_itemid`,`hit_date`),
  KEY `hit_user` (`hit_user`),
  KEY `hit_mainid` (`hit_mainid`,`hit_date`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

计算中的问题与作为乘数的hit_paylevel有关。默认值为1,另一个选项为2或3,这实际上是当天收益的两倍或三倍。

如果我遍历这些日子,那么每日day_earnings是正确的,只是当我对它们进行分组时,它会将所有内容计算为付费级别1.如果用户在开头是1级,并且稍后升级到更高水平。如果用户从一开始就支付2级,它也会正确计算所有内容。

2 个答案:

答案 0 :(得分:1)

这不应该是sum(hit_uniques * hit_paylevel) / 1000吗?

答案 1 :(得分:1)

像@Denis一样说:

将查询更改为

SELECT hit_paylevel, sum(hit_uniques) as day_unique_hits
       , sum(hit_uniques * hit_paylevel) / 1000 as day_earnings
       , hit_date 
FROM daily_hits 
WHERE hit_user = 'xxx' AND hit_date >= '2011-05-01' AND hit_date < '2011-06-01' 
GROUP BY hit_user;

为什么这样可以解决问题
在总和之后hit_paylevel ,首先对所有hit_uniques求和,然后选择一个随机hit_paylevel将其乘以。
不是你想要的。如果您在总和内部执行两个列,则MySQL将配对正确的hit_uniqueshit_paylevels

分组的危险
这是MySQL要记住的重要事项 group by子句与其他数据库的工作方式不同 在MSSQL *(或Oracle或PostgreSQL)上你会遇到错误

  

非聚合表达式必须出现在group by子句

或者就此而言。

在原始查询中,hit_paylevel不在聚合(总和)中,并且它也不在group by子句中,因此MySQL只是随机选择一个值。