MySQL ORDER BY FIELD на месяцы

У меня есть таблица с названием months — она ​​содержит все 12 месяцев календаря, идентификаторы соответствуют номеру месяца.

Я буду запускать запрос, чтобы получить 2 или 3 последовательных месяца из этой таблицы, например

  • Апрель Май
  • Июнь Июль Август
  • Декабрь и январь

Однако я хочу убедиться, что всякий раз, когда декабрь является январем и извлекается, он извлекает их в этом порядке, а не с января по декабрь. Вот что я пробовал:

SELECT * FROM `months`

WHERE start_date BETWEEN <date1> AND <date2>

ORDER BY
    FIELD(id, 12, 1)

Это работает для декабря и января, но теперь, когда я пытаюсь получить январь и февраль, он выполняет их в неправильном порядке, например, «февраль — январь» — я предполагаю, потому что мы указали 1 в ORDER BY в качестве последнего значения.

Кто-нибудь знает правильный способ добиться этого? Как я уже упоминал, это также должно работать в течение 3 месяцев, поэтому, например, «ноябрь, декабрь, январь» и «декабрь, январь, февраль» следует извлекать все в указанном порядке.

Я не понимаю. Ваш вопрос касается января и февраля, но ваш запрос относится к декабрю и январю!?!   —  person MAXIM    schedule 09.05.2020

Я думаю, нам нужен вопрос, более направленный на реальную проблему   —  person MAXIM    schedule 09.05.2020

Как вы передадите список номеров?   —  person MAXIM    schedule 09.05.2020

См. также:  Как запустить команду cmd с помощью PowerShell
Понравилась статья? Поделиться с друзьями:
IT Шеф
Комментарии: 3
  1. MAXIM

    Если вы хотите сначала декабрь, а остальные месяцы по порядку, тогда:

    order by (id = 12) desc, id
    

    MySQL обрабатывает логические значения как числа, где «1» означает истину, а «0» — ложь. desc ставит 12 на первое место.

    РЕДАКТИРОВАТЬ:

    Чтобы справиться с более общим случаем, вы можете использовать оконные функции. Если предположить, что числа идут подряд, проблема усложняется. Это будет работать для интервалов в 2 и 3 месяца:

    order by (case min(id) over () > 1 then id end),
             (case when id > 6 1 else 2 end),
             id
    

    Я не хочу думать о более общем решении, основанном только на месяцах. В конце концов, вы можете просто использовать:

    order by start_date
    

    Или, если у вас есть запрос агрегирования:

    order by min(start_date)
    

    чтобы решить настоящую проблему.

    Спасибо чувак! Иногда мы слишком усложняем! order by start_date — это все, что мне нужно для правильной работы! Спасибо еще раз :) person MAXIM; 09.05.2020

  2. MAXIM

    Это неправильно «решение mysql»:

    with cte (id, month) AS (
      select id, month from months 
      union all 
      select id, month from months
        ) 
    , cte1 (id, month, r) as (select id, month, row_number() over() as r from cte ) 
    select * from cte1 
      where id in (12, 1) 
               and r >= 12 order by r limit 2 ;
    
    
  3. MAXIM
    DECLARE 
     @monthfrom int = 12,
     @monthto int = 1;
    
    with months as (select 1 m
        union all
        select m+1 from months where m<12)
    
    
     select m
     from months
     where m in (@monthfrom,@monthto)
     order by
        case when @monthfrom>@monthto
        then
            m%12
        else    
            m
        end
    

    результат:

    12
    1
    

    В основном в MySQL это можно сделать так же:

    set @from =12;
    set @to =1;
    with recursive months(m) as (
      select 1 m 
      union all 
      select m+1 from months where m<12)   
    select * 
    from months 
    where m in (@from,@to) 
    order by case when @from>@to then m%12 else m end;
    
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: