MySQL, многократный GROUP BY
SELECT COUNT(*) FROM (SELECT `UserID`,`Hour` WHERE `Hour`>12 AND `Hour`<18 AND COUNT(*)>=2 GROUP BY CONCAT(`UserID`,'_',`Hour`) FROM `MyTable`) GROUP BY `Hour`
И ещё такой вопрос- есть таблица с PRIMARY KEY ID (он используется, т.е. удалять этот столбец нельзя и есть столбец, в котором записано время - оно монотонно не убывает при возрастании ID. Можно ли как-нибудь ускорить выборку по времени, не заводя при этом ещё один индекс для него?
SELECT COUNT(*) FROM (SELECT `UserID`,`Hour` WHERE `Hour`>12 AND `Hour`<18 GROUP BY CONCAT(`UserID`,'_',`Hour`) FROM `MyTable`) GROUP BY `Hour`а зачем CONCAT? разве такой запрос не дает тоже самое?
SELECT COUNT(*) FROM (SELECT `UserID`,`Hour` FROM `MyTable` WHERE `Hour`>12 AND `Hour`<18 GROUP BY `UserID`,`Hour` ) GROUP BY `Hour`
и вообще странно, как-то, разве с твоим GROUP BY с CONCAT, MySql не ругается, на `UserID`,`Hour` в SELECT?
не знаю как в MySql, но в MsSql можно через COUNT(DISTINCT) сделать:
SELECT COUNT(DISTINCT 'UserID')
FROM 'MyTable'
WHERE 'Hour'>12 AND 'Hour'<18
GROUP BY 'hour'
хотя план такой же получается, сам запрос немного проще выглядит
наиболее эффективно такой запрос будет выполняться, когда есть индекс с ключом ('hour', 'UserID' хотя через индекс с ключом 'hour' тоже скорее всего довольно быстро получится
а зачем CONCAT? разве такой запрос не дает тоже самое?Проблема в том, что я несмог найти описание GROUP BY, и не знал, как он работает с несколькими выражениями (если вообще работает).
можно в GROUP BY использовать несколько выражений, тогда в одну группу будут попадать все строки, где по каждому выражению из GROUP BY совпадают значения
SELECT COUNT(DISTINCT 'UserID')Спасибо, так, наверное, получится.
FROM 'MyTable'
WHERE 'Hour'>12 AND 'Hour'<18
GROUP BY 'hour'
Записей на один и тот же Hour не так много - индекс на UserID ни к чему. Но сейчас там такая схема, как я уже описал - есть ещё столбец ID, и Hour возрастают с увеличением ID, ID - Primary key, а на Hour индекса нету... как можно сделать, не создавая ещё один лишний индекс, чтобы при этом побыстрее подобные запросы выполнялись? (потому что, при сортировке по ID, получается, что уже всё отстортировано по Hour).
А что можно сделать с твоим способом, если хочется поставить дополнительное условие с UserID - например, чтобы смотреть только на те UserID, на которые для данного Hour не меньше двух записей?
SELECT COUNT(DISTINCT ...MySql это понимает
про то как сделать без индекса я не знаю
А что можно сделать с твоим способом, если хочется поставить дополнительное условие с UserID - например, чтобы смотреть только на те UserID, на которые для данного Hour не меньше двух записей?SELECT COUNT(DISTINCT 'UserID')
FROM 'MyTable' t1
WHERE 'Hour'>12 AND 'Hour'<18 AND (SELECT Count(*) FROM 'MyTable' t2 WHERE t1.UserID = t2.UserID AND t1.'hour' = t2.'hour') >= 2
GROUP BY 'hour'
не знаю как хорошо этот запрос будет исполняться, ничего лучше не придумывается
SELECT `Hour`,COUNT(*) FROM (SELECT `UserID`,`Hour` FROM (SELECT `UserID`,`Hour`,COUNT(*) as `RequestNum` FROM `MyTable` WHERE `Hour`>=123 AND `Hour`<456 GROUP BY `UserID`,`Hour`) as `sel2` WHERE `RequestNum`>=2) as `sel3` GROUP BY `Hour`
SELECT COUNT(DISTINCT userid)
FROM (
SELECT hour, userid
FROM MyTable
WHERE Hour>12 AND Hour<18
GROUP BY hour, userid
HAVING count(*) >= 2
) t
GROUP BY hour
да, так пожалуй лучше, а то в предыдущем моем запросе джойн вылазит
Оставить комментарий
kruzer25
Хочется оптимизировать что-то типаSELECT COUNT(*) FROM (SELECT `UserID`,`Hour` WHERE `Hour`>12 AND `Hour`<18 GROUP BY CONCAT(`UserID`,'_',`Hour`) FROM `MyTable`) GROUP BY `Hour`
Хотелось бы сделать что-то типа SELECT COUNT(`UserID`) FROM `MyTable` GROUP BY `Hour`,`UserID` - оно будет работать?
И вообще, как лучше тут сделать?
В refman практически ничего о GROUP BY нету...