LINUX.ORG.RU

mysql: select по датам

 , ,


0

1

Имеется вот такой запрос:

SELECT (SELECT SUM(length) FROM schedule_patients WHERE time LIKE '2013-11-16%') / SUM(TIMESTAMPDIFF(MINUTE,start,end)) FROM schedule_personnel WHERE start LIKE '2013-11-16%';
Он выдает нужное мне значение для одного дня 2013-11-16. Как можно не создавая процедуры, завернуть этот запрос в еще один SELECT, чтобы одним запросом получить таблицу где в одном столбце даты с сегодняшней на 2 недели вперед, а справа соответствующие значения



Последнее исправление: preepunk (всего исправлений: 1)

Хранить дату в «дате» и выбирать ее с помощью LIKE - неудачная идея.
Получать однородные значения в три разных столбца, один из которых в придачу будет пустым, не лучшее решение.

SELECT "past" AS `timeScale`,  /*условия запроса*/
UNION
SELECT "today" AS `timeScale`, /*условия запроса*/
UNION
SELECT "future" AS `timeScale`,  /*условия запроса*/
;
metrokto ★★
()
Последнее исправление: metrokto (всего исправлений: 1)
Ответ на: комментарий от metrokto

Не знаю насколько LIKE плохо работает для datetime, возможно вы правы. Однако о каких однородных значениях и трех столбцах говорите вы я не пойму. Мой запрос выдает таблицу 1х1 с одним значением для заданной даты. Мне нужно прогнать данный запрос для дат начиная с CURDATE() до CURDATE()+14 и получить таблицу 14x2 где слева даты - справа значения.

preepunk
() автор топика
Ответ на: комментарий от preepunk

Не уверен, что правильно, но как-то так:

SELECT
  a.Date dte,
  SUM(b.length)
  /
  SUM(TIMESTAMPDIFF(MINUTE, c.start, c.end)) length
FROM
(
  select curdate() + INTERVAL (a.a + (10 * b.a) + (100 * c.a)) DAY as Date
  from (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as a
  cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as b
  cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as c
) a
  LEFT JOIN schedule_patients b ON DATE(b.time) = a.Date
  LEFT JOIN schedule_personnel c ON DATE(c.start) = a.Date
WHERE a.Date >= CURDATE() AND a.Date <= DATE(NOW() + INTERVAL 2 WEEK)
GROUP BY a.Date

Wolfram
()
Ответ на: комментарий от preepunk

Не так понял.

Дело даже не в производительности LIKE. Условие с UNIX_TIMESTAMP () + 60 * 60 * 24 * 14 будет легче.

Как-то так:

SELECT
    `start`,
    (SELECT SUM(length) FROM schedule_patients WHERE time LIKE '2013-11-16%')
    / SUM(TIMESTAMPDIFF(MINUTE, start, end)) AS `value`
        FROM schedule_personnel
            WHERE  (UNIX_TIMESTAMP(`start`) >= UNIX_TIMESTAMP()
                AND UNIX_TIMESTAMP(`start`) <= UNIX_TIMESTAMP() + 60 * 60 * 24 * 14
;

metrokto ★★
()
Ответ на: комментарий от metrokto

посмотрите внимательнее у меня start должен быть конкрентной датой, ваш же пример делает интервал в 2 недели. мой вопрос не в том как модифицировать мой запрос, а как обернуть его, чтобы вместо строки '2013-11-16%' подставлялись даты с текущей до текущей + 14 дней. Учитывая что таблицы в которой были бы просто перечислены все даты бытия, пример от Wolfram так же не подходит.

Нужно создать своего рода итератор, не зависящий от таблиц, который начинается с CURDATE() и заканчивается через 14 дней.

Проблема в том чтобы обойтись одним запросом, без создания процедур, объявления переменных и т.п.

В конечном итоге должно быть

SELECT ИТЕРАТОР, SELECT (SELECT SUM(length) FROM schedule_patients WHERE time LIKE 'ИТЕРАТОР%') / SUM(TIMESTAMPDIFF(MINUTE,start,end)) FROM schedule_personnel WHERE start LIKE 'ИТЕРАТОР%');
Как реализовать нечто подобное?

preepunk
() автор топика
Ответ на: комментарий от preepunk

Если нужно выводить дату для которой нет записей в таблицах (schedule_patients, schedule_personnel), то сомневаюсь, что найдется какое-то _изящное_ решение.

Тут либо UNION, либо процедура или тупо создать таблицу с датами.

Wolfram
()
Ответ на: комментарий от preepunk

Туплю возможно, но у меня в условии «от текущего времени до текущего времени + 14 дней». Для задания даты старта отличной, от настоящего момента, в юникстаймштамп достаточно передать нужную дату.

metrokto ★★
()

Нужно выбрать записи между двумя датами? Что-то вроде

WHERE date BETWEEN NOW() AND NOW() + INTERVAL 2 WEEK

не?

eth1
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.