вывод с разными строками из разных столбцов из одной и той же таблицы SQL

Я пытаюсь рассчитать средние значения за последний 4-й месяц. Поэтому мне нужно получить 4-е значение каждого месяца

month_date | Month 1 | Month 2 | Month 3| Month 4
---------------------------------------------
 11   |   0    |   0     |   0    |   0
 10   |   2    |   0     |   0    |   0
 09   |   3    |   4     |   0    |   0
 08   |   8    |   7     |   9    |   0
 07   |   6    |   8     |   11   |   5
 06   |   3    |   4     |   0    |   8
 05   |   8    |   7     |   9    |   9
 04   |   6    |   8     |   11   |   5

[Ожидаемый результат]

 | Month 1 | Month 2 | Month 3| Month 4
----------------------------------------
  |   6     |   4     |   9    |   5

Что я пытался сделать

  • Я попытался ранжировать, исключая нули, такие как row_number (порядок по убыванию месяца) - это не сработало.

-Я пытался использовать функцию NULLS LAST, которая тоже не работала, потому что мне нужно заказывать на основе месяца, а не каждого месяца

Пожалуйста помоги


person dbA    schedule 03.12.2019    source источник
comment
Вы используете Oracle или MySQL?   -  person Gordon Linoff    schedule 04.12.2019
comment
либо один хорошо .   -  person dbA    schedule 04.12.2019
comment
Эта структура кажется неоптимальной. Таблица базы данных не является электронной таблицей   -  person Strawberry    schedule 04.12.2019
comment
Столбец в ожидаемом выводе A не соответствует другим. Есть 8, а не должно быть 6?   -  person Skamielina    schedule 04.12.2019


Ответы (1)


Это очень странное требование. Но вы можете сделать это, используя оконную функцию, чтобы получить первый ненулевой ранг. Затем добавьте три и используйте условную агрегацию:

select max(case when rank = month1_rank0 + 3 then month1 end) as month1,
       max(case when rank = month2_rank0 + 3 then month2 end) as month2,
       max(case when rank = month3_rank0 + 3 then month3 end) as month3,
       max(case when rank = month4_rank0 + 3 then month4 end) as month4       
from (select t.*,
             min(case when month1 <> 0 then rank end) over () as month1_rank0,
             min(case when month2 <> 0 then rank end) over ()  as month2_rank0,
             min(case when month3 <> 0 then rank end) over ()  as month3_rank0,
             min(case when month4 <> 0 then rank end) over ()  as month4_rank0
      from t
     ) t
person Gordon Linoff    schedule 03.12.2019
comment
Я пробовал это, но это не работает, потому что вам нужно сгруппировать по, если вы сгруппируете по - это все изменит. - person dbA; 04.12.2019
comment
@дба . . . В вашем наборе результатов есть только одна строка; следовательно, group by не подходит. Если у вас есть другой вопрос, задайте его как новый вопрос с соответствующими образцами данных и желаемыми результатами. - person Gordon Linoff; 04.12.2019
comment
В вашем подзапросе, поскольку вы выполняете функцию t.* - min(), поэтому последующая требует группы. Но действительно ценю ваши усилия за попытку. - person dbA; 04.12.2019
comment
@дбА . . . Кажется, я написал это, не подумав. Его там быть не должно. - person Gordon Linoff; 04.12.2019
comment
Я думаю, что так и должно быть, иначе мы не смогли бы получить значения месяца/2/3/4 из подзапроса, если подзапрос просто имеет номер min(rank) - person dbA; 04.12.2019
comment
@дбА . . . Я хотел оконные функции. - person Gordon Linoff; 05.12.2019