MySQL: создание одной строки в месяц для данных с диапазонами дат - PullRequest
1 голос
/ 09 февраля 2012

! Изменено!

У меня есть таблица (mySQL 5.0.x), которая содержит значения для диапазонов дат.

| id | link_id | type_id | value |  start | end    |
====================================================
|  1 |       1 |       1 |    10 | 201111 | 201202 |
|  2 |       1 |       2 |    20 | 201110 | 201201 |
|  3 |       1 |       1 |   100 | 201202 | 201202 |
|  4 |       2 |       1 |    40 | 201202 | 201203 |

, где

  • id - идентификатор записи
  • link_id для связи данных с другими таблицами
  • type_id предназначен для определения типа значения из другой таблицы
  • значение является числовым значением
  • начало и конец определяют диапазон (действительная дата или целое число для года и месяца)

Хитрость в том, что мне нужно представлять общую стоимость по типу и ссылке за определенный период ежемесячно. Таким образом, результат должен быть таким для диапазона 201201 - 201202:

| period | link_id | type_id | value |
======================================
| 201201 |       1 |       1 |    10 |
| 201202 |       1 |       1 |   110 |
| 201201 |       1 |       2 |    20 |
| 201201 |       2 |    NULL |  NULL |
| 201202 |       2 |       1 |    40 |

Я мог бы использовать PHP, чтобы поместить такую ​​информацию в базу данных, но есть некоторые недостатки. У меня есть сотни link_ids, многие type_id, а средняя разница между начальной и конечной датами составляет 30 месяцев, поэтому у меня будет множество строк.

1 Ответ

0 голосов
/ 09 февраля 2012

Вот один из способов сделать это.Я вставил $startMonth и $endMonth, чтобы вы могли видеть, как они играют. (У меня такое чувство, что это может быть упрощено, но это ускользает от меня):

SET @MONTH:=$startMonth-1;

SELECT month, link_id, type_id, SUM(value) AS value
FROM (SELECT @MONTH:=@MONTH+1 as month
      FROM foo f
      LIMIT $endMonth-$startMonth+1) a
LEFT JOIN foo f
 ON a.month >= f.start AND a.month <= f.end
GROUP BY link_id, type_id, a.month;

Путьэто работает: предположим, у вас есть таблица a:

+-------+
| month |
+-------+
|201201 |
|201202 |
+-------+

Тогда запрос, который вы ищете, будет намного проще обработать:

SELECT month, link_id, type_id, SUM(value) AS value
FROM a
LEFT JOIN foo
 ON a.month >= f.start AND a.month <= f.end
GROUP BY link_id, type_id, a.month;

Т.е. вы присоединяетесь к таблице a до foo, убедившись, что month находится между начальным и конечным периодами, а затем вы просто суммируете значение, группируя по месяцу, идентификатору ссылки и идентификатору типа.

Итак, проблема в том,как сгенерировать таблицу a, которая содержит числа от $startMonth до $endMonth.Следовательно:

SET @MONTH:=201200;
SELECT @MONTH:=@MONTH+1 AS month
FROM foo
LIMIT 2;

Это дает таблицу чисел, начинающихся с 201201 и с 2 строками, то есть до 201202.В этом запросе FROM foo является фиктивным - на самом деле не используется.

...