坚持使用MySQL和分组方式
我有一张有一些统计数据的桌子。例如: date userId attempts good bad 2010-08-23 1 5 4 1 2010-08-23 2 10 6 4 2010-08-23 3 6 3 3 2010-08-23 4 8 2 6 其中,x是当天所有坚持使用MySQL和分组方式,mysql,Mysql,我有一张有一些统计数据的桌子。例如: date userId attempts good bad 2010-08-23 1 5 4 1 2010-08-23 2 10 6 4 2010-08-23 3 6 3 3 2010-08-23 4 8 2 6 其中,x是当天所有(好/尝试)的总和,y是当天所有(坏/尝试)的总和。这可以在
(好/尝试)
的总和,y是当天所有(坏/尝试)
的总和。这可以在同一个查询中完成吗
我希望结果是
date userId score_good
2010-08-23 1 37%
2010-08-23 2 28% (60 / (80 + 60 + 50 + 25))
etc
日期用户ID分数\u良好
2010-08-23 1 37%
2010-08-23 2 28% (60 / (80 + 60 + 50 + 25))
等
或:
用户ID分数\良好\总计
1.
其中,score\u good\u total
是所有score\u good
得分的总和除以天数
我可以用子查询替换x和y,但这似乎不太合适,而且当我希望按月份或所有可用日期的总分对数据进行分组时,可能会导致太多的负载。我看不到比子查询更好的方法,因为任何有创意的方法都必须将所有行相加。优化器应该使您的子查询执行得非常好,而且非常简单
如果您确实需要更好的性能,那么您必须运行一个单独的作业,将所有“每日总”分数保存在另一个表中,因为它们在一天结束后不会改变。然后,您可以更改查询以仅在今天计算它;否则,使用上述“每日总分”表中的数据 这带来了一点SQL fu,但它在一个非常简单的查询中是完全可行的
// this would be the working query
SELECT
*,
@score := good / attempts * 100 AS score,
@t_score := (SELECT SUM(good / attempts * 100) FROM stats) as t_score ,
@score / @t_score as relative_score_good
FROM stats
下面我告诉你,你可以使用我用来复制和处理结果的值
这里需要注意的是内部的子查询,它是一个,因此对所有行只运行一次(只需运行查询,以查看这里实际上只有两个查询)
第二件要注意的事(和真正重要的一件!)是写为@变量的变量
出于复制的目的,您可以使用这两个命令重建示例表(如果您可以使用SQL向社区生成演示值,那就太好了)
希望有帮助!在我离开办公室的时候看到了这个问题,尽管有人会抢先回答。看电影,4个小时后还没有答案,万岁!;)但是如果优化器直接在他的查询中输入“SELECT SUM(good/attempts*100 FROM stats)”,优化器不会为他做类似的事情吗?谢谢,在这里我学到了更多关于MySQL的知识:)不过,我最终决定在表中存储更多的数据,这使得获取我想要的数据变得更加容易。
userId score_good_total
1 ...
// this would be the working query
SELECT
*,
@score := good / attempts * 100 AS score,
@t_score := (SELECT SUM(good / attempts * 100) FROM stats) as t_score ,
@score / @t_score as relative_score_good
FROM stats
// create the demo table
CREATE TABLE `test`.`stats` (
`date` DATE NOT NULL ,
`id` INT NOT NULL ,
`attempts` INT NOT NULL ,
`good` INT NOT NULL ,
`bad` INT NOT NULL ,
INDEX ( `id` , `attempts` , `good` , `bad` )
) ENGINE = MYISAM
// inject some values
INSERT INTO `test`.`stats` (`date`,`id`,`attempts` ,`good` ,`bad`)
VALUES
('2010-08-23', '1', '5', '4', '1'),
('2010-08-23', '2', '10', '6', '4'),
('2010-08-23', '3', '6', '3', '3'),
('2010-08-23', '4', '8', '2', '6');