sql:按x,y,z分组;返回按x,y分组,最低f(z)

时间:2010-03-18 12:07:37

标签: sql mysql group-by query-optimization

这适用于http://cssfingerprint.com

我收集关于我在不同浏览器上使用的不同方法执行速度有多快的时间统计数据,以便我可以优化抓取速度。另外,我有一个报告,说明每个方法为少数具有已知正确值的URL返回的内容,以便我可以告诉哪些方法在哪些浏览器上是假的。 (每个都不同,唉。)

相关表格如下:

CREATE TABLE `browser_tests` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `bogus` tinyint(1) DEFAULT NULL,
  `result` tinyint(1) DEFAULT NULL,
  `method` varchar(255) DEFAULT NULL,
  `url` varchar(255) DEFAULT NULL,
  `os` varchar(255) DEFAULT NULL,
  `browser` varchar(255) DEFAULT NULL,
  `version` varchar(255) DEFAULT NULL,
  `created_at` datetime DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL,
  `user_agent` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=33784 DEFAULT CHARSET=latin1

CREATE TABLE `method_timings` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `method` varchar(255) DEFAULT NULL,
  `batch_size` int(11) DEFAULT NULL,
  `timing` int(11) DEFAULT NULL,
  `os` varchar(255) DEFAULT NULL,
  `browser` varchar(255) DEFAULT NULL,
  `version` varchar(255) DEFAULT NULL,
  `user_agent` varchar(255) DEFAULT NULL,
  `created_at` datetime DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=28849 DEFAULT CHARSET=latin1

(user_agent在使用正则表达式从一小组已识别的值中插入到浏览器,版本和操作系统之前进行细分;我保留原始用户代理字符串以防万一。)

我有一个这样的查询告诉我每个非虚假的浏览器/版本/方法元组的平均时间:

select c, avg(bogus) as bog, timing, method, browser, version 
  from browser_tests as b inner join (
    select count(*) as c, round(avg(timing)) as timing, method, 
     browser, version from method_timings 
    group by browser, version, method 
    having c > 10 order by browser, version, timing
  ) as t using (browser, version, method)
  group by browser, version, method 
  having bog < 1 
  order by browser, version, timing;

返回类似的内容:

c  bog  tim  method       browser  version
88 0.8333 184 reuse_insert Chrome 4.0.249.89
18 0.0000 238 mass_insert_width Chrome 4.0.249.89
70 0.0400 246 mass_insert Chrome 4.0.249.89
70 0.0400 327 mass_noinsert Chrome 4.0.249.89
88 0.0556 367 reuse_reinsert Chrome 4.0.249.89
88 0.0556 383 jquery Chrome 4.0.249.89
88 0.0556 863 full_reinsert Chrome 4.0.249.89
187 0.0000 105 jquery Chrome 5.0.307.11
187 0.8806 109 reuse_insert Chrome 5.0.307.11
123 0.0000 110 mass_insert_width Chrome 5.0.307.11
176 0.0000 231 mass_noinsert Chrome 5.0.307.11
176 0.0000 237 mass_insert Chrome 5.0.307.11
187 0.0000 314 reuse_reinsert Chrome 5.0.307.11
187 0.0000 372 full_reinsert Chrome 5.0.307.11
12 0.7500 82 reuse_insert Chrome 5.0.335.0
12 0.2500 102 jquery Chrome 5.0.335.0
[...]

我想修改此查询以仅返回具有最低时间的浏览器/版本/方法 - 例如:

88 0.8333 184 reuse_insert Chrome 4.0.249.89
187 0.0000 105 jquery Chrome 5.0.307.11
12 0.7500 82 reuse_insert Chrome 5.0.335.0
[...]

我怎样才能这样做,同时仍然返回最低时间的方法?

我可以在应用程序端过滤它,但我宁愿在mysql中执行此操作,因为它可以更好地处理我的缓存。

1 个答案:

答案 0 :(得分:-1)

将所有最小时间记入临时表

SELECT 
  ID
  ,MIN(Time) AS MinTime 
INTO
  #tempMinTimes
FROM
  TABLE_NAME or (Sub Query)
GROUP BY
  ID

然后在ID字段上加入此临时表。

修改 我现在只看到有重复的ID,你需要在方法名称上删除重复的ID或组,然后在你的连接中使用ID和方法名称