Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Составление SQL-запросов > Сравнение частоты по count


Автор: dark0n 29.3.2016, 00:37
Господа, нужна помощь.
Есть таблица заходов на сайт вида
ID, DATE
1 01.01.15
1 01.02.15
1 01.05.15
2 01.01.15
2 01.03.15
1 01.01 16
1 01.03.16
и т.д.

Задача: Нужно, к примеру сравнить частоту заходов по ID в 15 и 16 годах и вывести те ID, где , к примеру, в 16 на 20% больше, чем в 15

В SQL я чайник.
Понимаю, как получить частоту за каждый год - к примеру
SELECT id,COUNT(id) FROM `test1` WHERE date>'2016-01-01' GROUP BY id
Могу это реализовать скажем на PHP. А как этого добиться SQL запросом. Чую, что вложенный запрос, но никак не соображу, как его сформулировать.

Заранее спасибо! 
ЗЫ: База - Postgree

Автор: Akina 29.3.2016, 09:04
Цитата(dark0n @  29.3.2016,  01:37 Найти цитируемый пост)
Понимаю, как получить частоту за каждый год - к примеру
Код

SELECT id,COUNT(id) FROM `test1` WHERE date>'2016-01-01' GROUP BY id

Не понимаешь. Вот кабы ты написАл типа
Код

SELECT id, COUNT(id) AS cnt
FROM test1 
WHERE EXTRACT(YEAR FROM date) = 2016
GROUP BY id
тогда я бы согласился с твоим утверждением.

Цитата(dark0n @  29.3.2016,  01:37 Найти цитируемый пост)
Нужно, к примеру сравнить частоту заходов по ID в 15 и 16 годах и вывести те ID, где , к примеру, в 16 на 20% больше, чем в 15

Напиши 2 запроса - на получение данных по 2015 и 2016 (см. выше) годам. Используй их в основном запросе как подзапросы в секции FROM, объединив, в зависимости от задачи, через INNER либо LEFT JOIN. В секции WHERE сравни cnt подзапросов, и оставь только нужные записи (при стороннем связывании потребуется использовать функцию COALESCE).

Автор: Zloxa 29.3.2016, 20:46
Цитата(dark0n @  29.3.2016,  01:37 Найти цитируемый пост)
Нужно, к примеру сравнить частоту заходов по ID в 15 и 16 годах и вывести те ID, где , к примеру, в 16 на 20% больше, чем в 15

Код

where date >= '2015-01-01' and date <'2017-01-01'
group by id
having
    1.2 < -- Отбираем все, что больше 120% от 2015 
        coalesce
        (
            count(case when date >= '2016-01-01' then 1 end)    -- count вернет 0, если не будет найдено записей за 2016
                / sum(case when date < '2016-01-01' then 1 end),  -- sum вернет null, если не будет найдено записей за 2015
            100500 -- у нас не может возникнуть ситуации, когда null в знаменателе при 0 в числителе, 
                   -- потому null в результате деления однозначно означает рост на дохулеард процентов, хавинг обязан вернуть истину
       )


Добавлено @ 20:58
И, http://www.postgresql.org/docs/9.1/static/datatype-datetime.html#DATATYPE-DATETIME-INPUT, литралы типа дата в постгре правильно писать 
Код

date '2015-01-01'

a не просто
Код

'2015-01-01'

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

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)