Дата между двумя другими датами без учета года

Я ищу что-то вроде человека здесь искал, только хотел бы использовать MySQL. Приведенную ниже таблицу можно найти в моей базе данных (упрощенно).

+------+------+------+------+
| id   | name | first| last |
+------+------+------+------+
|    1 | John | 1020 | 0814 |
|    2 | Ram  | 0827 | 0420 |
|    3 | Jack | 0506 | 0120 |
|    4 | Jill | 0405 | 0220 |
|    5 | Zara | 1201 | 1219 |
+------+------+------+------+

Прежде всего, запись должна быть случайной, а не с идентификатором 4, и мне нужна только одна запись. Я понял это: SELECT * FROM test WHERE id <> 4 ORDER BY rand() LIMIT 1.

В этой таблице столбцы «первый» и «последний» представляют собой даты в формате ммдд (оба числа целые). Так что Джон свободен большую часть года; с 20 октября по 14 августа. Zara, с другой стороны, доступна только в течение небольшого периода времени; с 1 по 19 декабря.

Мой вопрос: как мне изменить свой запрос, чтобы выбрать только доступных людей? Я не могу использовать «между», так как в случае Джона между 10:20 и 08:14 нет ничего.

Я просто не могу понять, должны быть другие люди, у которых есть похожая проблема... У кого-нибудь есть решение?

С уважением


person Niellles    schedule 18.08.2013    source источник
comment
Итак, first и last хранятся как целые числа, а не как даты? Почему некоторые первые значения идут после последних значений? В таком случае, как узнать, что нужно искать сначала › последним или последним › первым? Я также предполагаю, что вы имели в виду 20 октября.   -  person Andy G    schedule 18.08.2013
comment
Вы можете использовать BETWEEN, если сначала преобразуете свои «даты» в фактические значения MySQL DATE. Вы можете сделать это с помощью STR_TO_DATE(): STR_TO_DATE(first, '%m%d'). Однако проблема, которую отмечает @AndyG, остается.   -  person Tomas Creemers    schedule 18.08.2013
comment
@GreatBigBore Недостаточно добавить 10000 к последнему. В случае Джона 0101 следует рассматривать между 10:20 и 08:14, но не между 10:20 и 10 814.   -  person Barmar    schedule 18.08.2013


Ответы (1)


Нужно различать два случая.

  1. Когда first < last, даты относятся к одному и тому же году. Затем вы можете использовать between для сопоставления дат.

  2. Когда first > last, это означает, что last будет в следующем году. В данном случае совпадают даты date >= first OR date <= last.

Итак, ваше предложение WHERE должно быть:

WHERE IF(first < last, @date BETWEEN first AND last,
                       @date >= first OR date <= last)
person Barmar    schedule 18.08.2013
comment
Разве особый случай не должен быть BETWEEN last AND first, так как last < first в особом случае? - person SaganRitual; 18.08.2013
comment
@GreatBigBore Между 1020 и 0814 нет чисел. - person Barmar; 18.08.2013
comment
Однако я неправильно понял направление своих сравнений. Я исправил это. - person Barmar; 18.08.2013
comment
Хорошо, правильно. Я думал, что вы хотели добавить скорректированное значение года к датам. - person SaganRitual; 18.08.2013
comment
@ AnyG & Tomas Creemers: Я думал об этом, но, насколько мне известно, str_to_date() форматирует только даты... Кроме того, тогда мне пришлось бы добавить год, так как нет типа поля, который бы сохранял только mmdd... в моем случае просто нет доступного года, так как теоретически это продолжается вечно. @Barmar Таким образом, мой запрос при использовании php будет выглядеть так: SELECT * FROM test WHERE id <> 4 AND (IF(first < last, $date BETWEEN first AND last, $date >= first OR $date <= last)) ORDER BY rand() LIMIT 1. Я еще немного рассмотрю операторы IF в SQL! Спасибо за ваши ответы! - person Niellles; 18.08.2013