У меня есть две даты, и я хочу сохранить только строки, в которых определенная неделя находится между этими двумя датами. Мне нужно запустить это в течение 67+ разных недель, поэтому я хотел бы изменить приведенный ниже код, чтобы он работал быстрее и мне не приходилось каждый раз вводить 7 дней недели.
SELECT * FROM MY_DATA
WHERE ('05-JUNE-2017' BETWEEN start_date AND end_date
OR '06-JUNE-2017' BETWEEN start_date AND end_date
OR '07-JUNE-2017' BETWEEN start_date AND end_date
OR '08-JUNE-2017' BETWEEN start_date AND end_date
OR '09-JUNE-2017' BETWEEN start_date AND end_date
OR '10-JUNE-2017' BETWEEN start_date AND end_date
OR '11-JUNE-2017' BETWEEN start_date AND end_date);
«У меня два свидания». Я вижу 7 констант даты и два столбца даты. Я запутался.
Есть 2 константы даты start_date и end_date. В своем вопросе я говорю: «Мне нужно запустить это в течение 67+ разных недель», поэтому даты, которые я укажу, т.е. 06.05.2017-06.11.2017, нужно будет изменить 67+ раз. Я не хочу печатать еженедельные даты более 67 раз. Как сказано в вопросе.
@stickybit извините, SQL Oracle, этот тег был добавлен по ошибке.
Как вы «вводите» неделю? В вашем текущем коде у вас жестко запрограммированы семь разных (последовательных) дат. Вы просто указываете ОДНУ дату в качестве первого дня «недели» (независимо от того, воскресенье это, понедельник или что-то еще)? И хотите считать все семь дней, начиная с (и включая) «заданной» даты?
Также: НИКОГДА не используйте строки вместо дат. Пишите TO_DATE('07-JUNE-2017', 'dd-MONTH-yyyy')
(включая модель формата!) - и лучше всего использовать все числа, например 07-06-2017, чтобы код не зависел от языка (ваши коллеги в Бразилии или Италии могут запускать его без модификаций).
думаю проще будет понять что вам нужно, если добавить примерные данные и ожидаемый результат
Я думаю, что ваш запрос эквивалентен
SELECT * FROM MY_DATA WHERE ('05-JUNE-2017' BETWEEN start_date - 6 AND end_date );
где '05-JUNE-2017'
— начальный день недели, который вы ищете.
Теперь вы должны сделать это для всех начальных дней недели...
Это то, что вы ищете?
Нет, потому что что, если start_date — «06-JUNE-2017»?
Но когда вы говорите, что "определенная неделя приходится на промежуток между двумя датами", вы имеете в виду полностью или частично? Итак: если неделя идет с 5-го по 11-е число одного месяца, а ваша дата начала — 7-е, а end_date — 15-е, это действительная неделя?
Существующий код (который ОП считает правильным, просто слишком сложным) означает, что ОП ищет «частично» (перекрытие), а не «полностью». «Полностью» потребовалось бы логическое AND
; ОП использовал OR
.
Если частично, то ваш ответ правильный. соответственно поменяю свой
Я думаю, вы ищете что-то вроде следующего:
WITH weeks AS (SELECT TO_DATE('05-07-2017', 'DD-MM-RRRR') + LEVEL * 7 - 7 week_start
, TO_DATE('05-07-2017', 'DD-MM-RRRR') + LEVEL * 7 - 1 week_end
FROM dual
CONNECT BY LEVEL < 50)
SELECT *
FROM MY_DATA
JOIN WEEKS
ON MY_DATA.end_date >= weeks.week_start
AND MY_DATA.start_date <= weeks.week_end
Первая часть дает вам несколько недель подряд, а затем вы объединяете их со своими данными, чтобы получить желаемые результаты.
Почему вы настаиваете на RRRR
? Это не имеет смысла - это просто показывает невежество. Любой вид RR
или RRRR
существовал только около 2000 года, чтобы решить проблему Y2K (годы хранятся в виде двух цифр). Для четырехзначных годов RRRR
и YYYY
совпадают, и нет причин использовать RRRR
.
Как вы сказали - это не имеет значения, так почему вы настаиваете на изменении правильного ответа??? Это не имеет ничего общего с невежеством, просто нет смысла его менять...
Я не «настаиваю» на его изменении; Я один раз поменял, пытаясь помочь, ты поменял обратно, я оставил в покое. Я просто этого не понимаю. Вы так и не объяснили, почему используете RRRR
там, где большинство людей использовали бы YYYY
. Опять же, RRRR
существует только для решения устаревшей проблемы. Прошло уже 19 лет, так почему вы все еще используете RRRR
?
Например, при работе с формами оракула полезно использовать RRRR
, так как тогда пользователь может ввести дату с 2 или 4 цифрами, что в противном случае потребовало бы большого программирования. Таким образом, общее использование RRRR
вместо YYYY
имеет смысл независимо от проблемы Y2K, поскольку в некоторых случаях это все еще полезно, а в других нет никакой разницы...
Итак, у вас есть два интервала дат. Один от input_date
до input_date + 6
(обратите внимание: 6, а не 7; вы тоже считаете input_date
!) и другой от start_date
до end_date
. И вы хотите написать условие, которое означает, что два интервала перекрываются (имеют непустое пересечение).
Два интервала нет перекрываются, если один полностью предшествует другому. Итак, последний день одного интервала должен быть строго меньше первого дня другого интервала. Это может произойти одним из двух способов (в зависимости от того, какой интервал который стоит первым). Условие будет выглядеть так:
input_date + 6 < start_date OR end_date < input_date
Итак, это отрицание желаемого состояния. Примените к этому логический оператор NOT
; поэтому условие становится:
input_date + 6 >= start_date AND end_date >= input_date
Почему вы написали Oracle в заголовке, но пометили SQL Server? Который из них?