2014-12-11 4 views
1

Я работаю над улучшением некоторых запросов я унаследовал, и был интересно, если это было возможно сделать следующее - учитывая таблицу the_table, которая выглядит следующим образом:многоступенчатого MySQL GROUP BY без подзапроса

id uri 
    ---+------------------------- 
    1 /foo/bar/x 
    1 /foo/bar/y 
    1 /foo/boo 
    2 /alpha/beta/carotine 
    2 /alpha/delic/ipa 
    3 /plastik/man/spastik 
    3 /plastik/man/krakpot 
    3 /plastik/man/helikopter 

В качестве неявного промежуточного шага я хотел бы сгруппировать их на 1-й + 2-й кортеж uri. Результаты этого шага будет выглядеть так:

id base   
    ---+--------------- 
    1 /foo/bar  
    1 /foo/boo  
    2 /alpha/beta 
    2 /alpha/delic 
    3 /plastik/man 

И конечный результат будет отражать количество уникальных tuple1 + tuple2 значений, на уникальный id:

id cnt 
    ---+----- 
    1 2 
    2 2 
    3 1 

я могу достичь этих результатов, но не без выполнения подзапроса (чтобы получить результаты неявного шага, упомянутого выше), а затем выберите/сгруппируйте его. Что-то вроде:

SELECT 
    id, 
    count(base) cnt 
FROM (
    SELECT 
    id, 
    substring_index(uri, '/', 3) AS base 
    FROM the_table 
    GROUP BY id, base 
) 
GROUP BY id; 

Моей причины для желающих избежать подзапроса в том, что я работаю с набором данных довольно большой (20M строки), и подзапрос становится очень дорогим. Гут говорит мне, что это не выполнимо, но полагал, что я спросить SO ...

ответ

2

Там нет необходимости для подзапроса - вы можете использовать count с distinct для достижения того же результата:

SELECT 
    id, 
    count(distinct substring_index(uri, '/', 3)) AS base 
FROM the_table 
GROUP BY id 

BTW - это возвращает количество 1 для id 3 - я предполагаю, что это была опечатка в вашей публикации.

+0

Я немного подробнее рассмотрю здесь, спасибо. И да, вы правильно относитесь к опечатке в моем вопросе. Исправлена. – Madbreaks

+0

Это так просто, я не могу поверить, что не пробовал. Благодаря! – Madbreaks