2013-07-18 2 views
0

У меня возникли проблемы с написанием краткого кода, чтобы эффективно генерировать желаемый результат (в нескольких миллионах записей DB).MySQL GROUP BY с сортировкой

  • деталь будет сгруппирована по time
  • элементов будет выбран путем provider того, что В имеет приоритет над A (и С над В)
  • значения должно соответствовать значению выбранного поставщика

Таблица против желаемого результата:

// given this table 
id | provider | time  | value 
---+----------+------------+----------- 
1 | A  | 2013-07-01 | 0.1 
2 | A  | 2013-07-02 | 0.2 
3 | B  | 2013-07-02 | 0.3 
4 | A  | 2013-07-03 | 0.4 

// extrapolate this result 
---+----------+------------+----------- 
1 | A  | 2013-07-01 | 0.1 
3 | B  | 2013-07-02 | 0.3 
4 | A  | 2013-07-03 | 0.4 

Запросы генерировать таблицу и данные:

data_teste CREATE TABLE `data_teste` (`id` int(11) unsigned NOT NULL AUTO_INCREMENT,`provider` varchar(12) NOT NULL,`time` date NOT NULL,`value` double NOT NULL,PRIMARY KEY (`id`),UNIQUE KEY `index` (`provider`,`time`),KEY `provider` (`provider`),KEY `time` (`time`)) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
INSERT INTO data_teste(`provider`, `time`, `value`) VALUES('A', '2013-07-01', 0.1),('A', '2013-07-02', 0.2),('B', '2013-07-02', 0.3),('A', '2013-07-03', 0.4); 

Это классическая проблема group_by/сортировать оконном.

спасибо.

+0

Я думаю, вы должны объяснить, почему это желаемый результат. –

+0

@EvanMulawski есть разные провайдеры, чем приносить данные по временному ряду, но когда есть перекрытие в поле времени, я хочу, чтобы данные от провайдера B имели приоритет над A (и etecetera) – Frankie

ответ

1
select d.* 
from data_teste d 
inner join 
(
    select `time`, max(provider) mp 
    from data_teste 
    group by `time` 
) x on x.mp = d.provider 
    and x.`time` = d.`time` 
order by `time` asc, 
      provider desc 
+0

Это определенно более элегантно, чем то, что я имел. Все еще выполняет медленные (до 4 секунд), но это гораздо более кратким, что я, вероятно, могу ускорить его, запросив только ограниченные ведра времени. Благодаря! – Frankie

+0

Вы можете использовать 'explain select ...', чтобы узнать, где узкое место производительности. –

+0

Все индексы выглядят хорошо. Основное узкое место на самом деле приходится группировать с таким размером набора данных. Он может управляться и контролироваться путем ограничения его временного диапазона. Благодаря! – Frankie

0

Насколько хорошо это действует?

SELECT 
    * 
FROM 
    `data_teste` dt1 
    LEFT JOIN `data_teste` dt2 ON (dt2.time = dt1.time 
            AND dt2.provider > dt1.provider) 
WHERE 
    dt2.ID IS NULL