Ответы пользователя по тегу SQL
  • ORDER с GROUP BY в прикрепленной таблице?

    @a1go1ov
    Scala fan, Java developer
    Я не специалист в MySQL, но вообще по стандарту SQL в блоке select можно указывать только те поля, которые либо указаны в блоке group by (то есть по которым осуществляется группировка), либо передаются в групповую функцию, такую как sum, max и т.д.
    Судя по документации, MySQL позволяет не придерживаться данного правила, но тогда для полей не удовлетворяющих озвученным выше условиям выбирается произвольная строка из группы.
    Для того, чтобы отключить в MySql расширенное трактование GROUP BY, нужно включить режим ONLY_FULL_GROUP_BY

    Относительно вашего запроса, повторная выборка столбца p.post_date, после того как вы указали, что хотите получить записи с последней датой - max(p.post_date), явно не имеет смысла и ломает группировку. Уберите ее, ну и в целом лучше придерживаться стандарта, так ваши запросы будет легче портировать если вы будете мигрировать на другую СУБД, да и недопонимания будет меньше.
    Ответ написан
    Комментировать
  • Как сравнить текущее значение COUNT(*) с предыдущим?

    @a1go1ov
    Scala fan, Java developer
    В oracle вашу задачу можно решить при помощи оператора model:

    -- данные для выборки
    with data as (
      select 1 as id, 2009 as year, 3 as month, 50  as count from dual union all
      select 2 as id, 2009 as year, 4 as month, 100 as count from dual union all
      select 3 as id, 2009 as year, 5 as month, 133 as count from dual union all
      select 4 as id, 2009 as year, 7 as month, 2   as count from dual union all
      select 5 as id, 2010 as year, 2 as month, 98  as count from dual union all
      select 6 as id, 2010 as year, 4 as month, 600 as count from dual
    )
    
    -- сам запрос
    select year, month, count, round(result, 2) as increment_rate
    from data
    model
      -- генерируем порядковый номер для строк, 
      -- по которому будем осуществлять доступ к данным
      dimension by (row_number() over (order by year, month) rn)
      -- указываем столбцы, которые будут отображаться/участвовать в расчетах
      -- также добавляем несуществующий столбец result, 
       -- что бы в дальнейшем помещать в него результат вычислений
      measures (count, year, month, 0 result)
      rules (
        -- делаем соответствующие вычисления
        result[any] = greatest(decode(nvl(count[cv(rn)-1],0), 0, 0, count[cv(rn)] / count[cv(rn)-1])*100 - 100, 0)
      )


    Результат:
    +------+-------+-------+---------------+
    | YEAR | MONTH | COUNT | INCREMENT_RATE|
    +------+-------+-------+---------------+
    | 2009 | 3     | 50    |  0            |
    +------+-------+-------+---------------+
    | 2009 | 4     | 100   | 100           |
    +------+-------+-------+---------------+
    | 2009 | 5     | 133   | 33            |
    +------+-------+-------+---------------+
    | 2009 | 7     | 2     | 0             |
    +------+-------+-------+---------------+
    | 2010 | 2     | 98    |  4800         |
    +------+-------+-------+---------------+
    | 2010 | 4     | 600   | 512,24        |
    +------+-------+-------+---------------+

    Пояснения к формуле:
    result[any] = greatest(decode(nvl(count[cv(rn)-1],0), 0, 0, count[cv(rn)] / count[cv(rn)-1])*100 - 100, 0)

    Слева от знака равно мы указываем, что для каждой ячейки (ключевое слово any ) в столбце result в качестве значения мы рассчитываем выражение справа от знака равно.
    Для того, что бы рассчитать величину прироста, необходимо взять значение за текущий временной период, разделить его на значение за предыдущий временной период, затем умножить на 100% и вычесть 100%.
    Но так как у нас для первого периода в таблице (для первой строки), нет предыдущего периода, а также значением в предыдущем периоде может быть 0, то возникает ошибка деления на 0. Поэтому нужно эту ситуацию обработать, для чего в формуле используется decode, который проверяет, если значение предыдущего периода не существует или равно 0, тогда необходимо возвратить 0, если же значение предыдущего периода не равно 0, то рассчитываем отношение. Также используется функция greatest, для того, чтобы вместо отрицательных значений отображать 0 (когда результат предыдущего периода больше текущего, соответственно прироста нет).
    Если вместо прироста необходимо рассчитать процент роста, то вычитание 100% нужно убрать.
    Ответ написан
    Комментировать