sql: сгруппировать по x, y, z; возврат сгруппированы по x, y с наименьшим f (z) - PullRequest
0 голосов
/ 18 марта 2010

Это для 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 разбит перед вставкой в ​​браузер, версию и ОС из небольшого списка распознанных значений с использованием регулярных выражений; я сохраняю исходную строку 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 голосов
/ 18 марта 2010

Получить все минимальное время во временную таблицу

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

Затем Inner Join в эту временную таблицу в поле ID.

EDIT Я только видел, что теперь есть дубликаты идентификаторов, вам нужно также избавиться от дубликатов идентификаторов или группы в имени метода, а затем в своем соединении использовать идентификатор и имя метода

...