sql — Выборка по дню недели
Вопрос задан
Изменён 7 лет 3 месяца назад
Просмотрен 1k раз
Есть таблица со столбцами соответствующими дню недели (Mo, Tu, We, Th, Fr, Sa, Su
) типа time(7)
. Если в этот день есть занятие, то будет стоять время.
Надо выбрать все занятия сегодня. Не могу сообразить, как составить запрос.
Как то так:
select * from tableX where ELT(DAYOFWEEK(NOW()),Su, Mo, Tu, We, Th, Fr, Sa) is not null
DAYOFWEEK(NOW()
возвращает номер дня недели, 1-воскресенье, 2-понедельник и т.п. ELT()
выдает один из своих параметров по номеру соответствующий первому параметру, т.е. в зависимости от дня недели он выдаст один из столбцов, который мы и проверяем на заполненность.
field & (1 << DAYOFWEEK(NOW()) != 0
. Или делаем текстовое поле в котором каждый день недели кодируем одной буквой или цифрой и ищем like, например понедельник и пятница обозначаем ‘MF’.
4
В Oracle, например, можно сделать так:
SELECT * FROM test WHERE time = substr(to_char(sysdate, 'Dy', 'NLS_DATE_LANGUAGE = ENGLISH'), 0, 2)
где time
— ваш столбец с днем недели,'NLS_DATE_LANGUAGE = ENGLISH'
возвращает день недели в английском варианте (возвращает 3 буквы дня недели, поэтому берем подстроку из первых двух букв).
Зарегистрируйтесь или войдите
Регистрация через Google Регистрация через Facebook Регистрация через почтуОтправить без регистрации
ПочтаНеобходима, но никому не показывается
Отправить без регистрации
ПочтаНеобходима, но никому не показывается
By clicking “Отправить ответ”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.
Дата/время · Loginom Help
AddDay AddDay(Дата, Количество)
Функция возвращает значение аргумента Дата, увеличенного на указанное Количество дней. Количество может быть и отрицательным, тогда функция возвратит дату на указанное количество дней раньше указанной даты. AddMonth(Дата, Количество)
Функция возвращает значение аргумента Дата, увеличенного на указанное Количество месяцев. Количество может быть и отрицательным, тогда функция возвратит дату на указанное количество месяцев раньше указанной даты. Если указанный день месяца больше, чем последний день получившегося месяца, то функция устанавливает дату на последний день получившегося месяца. AddQuarter(Дата, Количество)
Функция возвращает значение аргумента Дата, увеличенного на указанное Количество кварталов. Количество может быть и отрицательным, тогда функция возвратит дату на указанное количество кварталов раньше указанной даты. Если указанный день месяца больше, чем последний день месяца получившегося квартала , то функция устанавливает дату на последний день месяца получившегося квартала. AddWeekAddWeek(Дата, Количество)
Функция возвращает значение аргумента Дата, увеличенного на указанное Количество недель. Количество может быть и отрицательным, тогда функция возвратит дату на указанное количество недель раньше указанной даты. AddYearAddYear(Дата, Количество)
Функция возвращает значение аргумента Дата, увеличенного на указанное Количество лет. Количество может быть и отрицательным, тогда функция возвратит дату на указанное количество лет раньше указанной даты. DateTimeToStr(Дата_время [, Формат_даты [, Формат_времени]])
Возвращает строковое представление аргумента Дата_время. Примеры формата даты: «DD.MM.YY» — преобразует дату в формат «день.месяц.год» («25.12.04») «MM/DD/YYYY» — преобразует дату в формат «месяц.день.год» («12/25/2004») Примеры формата времени: «H:NN» — преобразует время в формат «часы:минуты» («9:53») «HH:NN:SS» — преобразует время в формат «часы:минуты:секунды» («09:05:53») DateToStr(Дата [, Формат_даты])
Возвращает строковое представление аргумента Дата. Примеры формата даты: «DD.MM.YY» — преобразует дату в формат «день.месяц.год» («25.12.04») «MM/DD/YYYY» — преобразует дату в формат «месяц.день.год» («12/25/2004») DayDay(Дата)
Возвращает день по заданной дате. DayOfWeekDayOfWeek(Дата)
Возвращает день недели заданной даты. DaysBetweenDaysBetween(Дата1, Дата2)
Возвращает полное количество дней между двумя датами. EncodeDateEncodeDate(Год, Месяц, День)
Функция возвращает дату, сформированную из указанных аргументов. EncodeDateTimeEncodeDateTime(Год, Месяц, День, Часы, Минуты, Секунды)
Функция возвращает дату и время, сформированные из указанных аргументов. EncodeTimeEncodeTime(Часы, Минуты, Секунды)
Функция возвращает время, сформированное из указанных аргументов. HourHour(ДатаВремя)
Возвращает час по заданной дате/времени. Minute(ДатаВремя)
Возвращает минуты по заданной дате/времени. MonthMonth(Дата)
Возвращает месяц по заданной дате. MonthsBetweenMonthsBetween(Дата1, Дата2)
Возвращает полное количество месяцев между двумя датами. NowNow()
Возвращает текущую дату и время. Так как текущая дата и время — это время вычисления выражения, которое считается каждый раз при получении значения этого выражения, например, при просмотре результата в виде таблицы или при выполнении экспорта данных, то можно, при наличии параметра выражения «Кэшировать рассчитанные значения выражения» включить эту опцию. Second(ДатаВремя)
Возвращает секунды по заданной дате/времени. StartOfTheWeekStartOfTheWeek(Дата)
Функция возвращает дату начала указанной недели в соответствии со стандартом ISO 8601, по которому неделя начинается с понедельника и заканчивается воскресеньем. StrToDate(Аргумент [, Формат])
Функция конвертирует строку, содержащую дату в формат типа «Дата/Время». Примеры формата: «DD.MM.YY» — говорит, что Аргумент содержит строки вида «25.12.04»; «DD/MM/YY/HH:NN:SS» — говорит, что Аргумент содержит строки вида «25/12/04/12:44:54»; TodayToday()
Возвращает текущую дату. Так как текущая дата — это дата вычисления выражения, которое считается каждый раз при получении значения этого выражения, например, при просмотре результата в виде таблицы или при выполнении экспорта данных, то можно, при наличии параметра выражения «Кэшировать рассчитанные значения выражения» включить эту опцию. WeekWeek(Дата)
Возвращает номер недели в году по заданной дате в соответствии со стандартом ISO 8601, по которому неделя начинается с понедельника и заканчивается воскресеньем. Первая неделя года начинается с понедельника, для дней с 1 января по первый понедельник возвращается номер последней недели предыдущего года. YearYear(Дата)
Возвращает год по заданной дате. YearsBetweenYearsBetween(Дата1, Дата2)
Возвращает полное количество лет между двумя датами. |
ГОД* / ДЕНЬ* / НЕДЕЛЯ* / МЕСЯЦ / КВАРТАЛ
- Категории:
Функции даты и времени
Извлекает соответствующую часть даты из даты или метки времени.
Эти функции являются альтернативой использованию функции DATE_PART (или EXTRACT) с эквивалентной частью даты (см. Поддерживаемые части даты и времени).
- См. также:
ЧАС/МИНУТА/СЕКУНД
Синтаксис
ГОД() ГОДНЕДЕЛИ( ) YEAROFWEEKISO( ) ДЕНЬ( ) ДЕНЬFМЕСЯЦ( ) ДЕНЬНЕДЕЛИ( ) DAYOFWEEKISO( ) ДЕНЬГОД( ) НЕДЕЛЯ( ) НЕДЕЛЯFYEAR( ) НЕДЕЛЯ( ) МЕСЯЦ( ) КВАРТАЛ( )
Замечания по использованию
Название функции | Часть даты, извлеченная из ввода Дата/отметка времени | Возможные значения |
---|---|---|
ГОД | Год | Любой действительный год (например, 2017) |
ГОДНЕДЕЛЯ [1] | Год, к которому относится извлеченная неделя | Любой действительный год (например, 2017) |
ГОДНЕДЕЛИКИСО | То же, что и YEAROFWEEK, за исключением использования семантики ISO | Любой действительный год (например, 2017) |
ДЕНЬ, ДЕНЬМЕСЯЦ | День (число) месяца | от 1 до 31 |
ДЕНЬ НЕДЕЛИ [1] | День (номер) недели | от 0 до 7 |
ДЕНЬ НЕДЕЛИКИСО | То же, что и DAYOFWEEK, за исключением использования семантики ISO | от 1 до 7 |
ДЕНЬГОД | День (число) года | от 1 до 366 |
НЕДЕЛЯ, НЕДЕЛЯФГОД [1] | Неделя (номер) года | от 1 до 54 |
УИКИСО | То же, что и WEEK, за исключением использования семантики ISO | от 1 до 53 |
МЕСЯЦ | Месяц (число) года | от 1 до 12 |
КВАРТАЛ | Квартал (номер) года | от 1 до 4 |
[1] Результаты определяются значениями, установленными для параметров сеанса WEEK_OF_YEAR_POLICY и/или WEEK_START.
Дополнительные сведения о семантике ISO и параметре см. в разделе Недели и рабочие дни календаря.
Примеры
Ниже показано использование функций ГОД
, МЕСЯЦ
, ДЕНЬ
, ДЕНЬНЕДЕЛИ
, ДЕНЬГОД
,
и КВАРТАЛ
:
ВЫБЕРИТЕ '2013-05-08T23:39:20.123-07:00'::TIMESTAMP AS tstamp, ГОД(tstamp) КАК "ГОД", КВАРТАЛ(tstamp) КАК "КВАРТАЛ ГОДА", МЕСЯЦ(tstamp) КАК "МЕСЯЦ", ДЕНЬ(tstamp) КАК "ДЕНЬ", DAYOFMONTH(tstamp) КАК "ДЕНЬ МЕСЯЦА", DAYOFYEAR(tstamp) КАК "ДЕНЬ ГОДА"; +-------------------------+---------------------+---------------- -+-------+-----+---------------+-------------+ | ТСТАМП | ГОД | КВАРТАЛ ГОДА | МЕСЯЦ | ДЕНЬ | ДЕНЬ МЕСЯЦА | ДЕНЬ ГОДА | |-------------------------+---------------------+---------------- -+-------+-----+---------------+-------------| | 2013-05-08 23:39:20.123 | 2013 | 2 | 5 | 8 | 8 | 128 | +-------------------------+---------------------+---------------- -+-------+-----+---------------+-------------+
Ниже показано использование функций НЕДЕЛЯ
, НЕДЕЛЯ
, НЕДЕЛЯГОД
, ГОДНЕДЕЛЯ
и ГОДНЕДЕЛИISO
. Параметр сеанса WEEK_OF_YEAR_POLICY указывает, что первая неделя
года — это неделя, которая содержит 1 января этого года.
ALTER SESSION SET WEEK_OF_YEAR_POLICY = 1;ВЫБОР '2016-01-02T23:39:20.123-07:00'::TIMESTAMP AS tstamp, НЕДЕЛЯ(tstamp) КАК "НЕДЕЛЯ", НЕДЕЛЯ (tstamp) КАК "НЕДЕЛЯ ISO", НЕДЕЛЯГОД(tstamp) КАК "НЕДЕЛЯ ГОДА", YEAROFWEEK(tstamp) КАК "ГОД НЕДЕЛИ", YEAROFWEEKISO(tstamp) AS "ГОД НЕДЕЛИ ISO" ; +-------------------------+------+-----------+----- ---------+---------------+----+ | ТСТАМП | НЕДЕЛЯ | НЕДЕЛЯ ИСО | НЕДЕЛЯ ГОДА | ГОД НЕДЕЛИ | ГОД НЕДЕЛИ ISO | |-------------------------+------+-----------+----- ---------+---------------+------------------| | 2016-01-02 23:39:20.123 | 1 | 53 | 1 | 2016 | 2015 | +-------------------------+------+-----------+----- ---------+---------------+----+
Далее также демонстрируется использование функций НЕДЕЛЯ
, НЕДЕЛЯ
, НЕДЕЛЯГОД
, ГОДНЕДЕЛЯ
и ГОДНЕДЕЛИISO
. Параметр сеанса WEEK_OF_YEAR_POLICY указывает, что первая неделя
года — это первая неделя года, которая содержит не менее 4 дней из этого года. (Так, например,
неделя с 26 декабря 2010 г. по 1 января 2011 г. считается последней неделей 2010 г., а не первой неделей
2011 г., потому что, хотя он содержит 1 января 2011 г., менее половины недели приходится на 2011 г.)
ИЗМЕНИТЬ НАБОР СЕССИИ WEEK_OF_YEAR_POLICY = 0;ВЫБОР '2016-01-02T23:39:20.123-07:00'::TIMESTAMP AS tstamp, НЕДЕЛЯ(tstamp) КАК "НЕДЕЛЯ", НЕДЕЛЯ (tstamp) КАК "НЕДЕЛЯ ISO", НЕДЕЛЯГОД(tstamp) КАК "НЕДЕЛЯ ГОДА", YEAROFWEEK(tstamp) КАК "ГОД НЕДЕЛИ", YEAROFWEEKISO(tstamp) AS "ГОД НЕДЕЛИ ISO" ; +-------------------------+------+-----------+----- ---------+---------------+----+ | ТСТАМП | НЕДЕЛЯ | НЕДЕЛЯ ИСО | НЕДЕЛЯ ГОДА | ГОД НЕДЕЛИ | ГОД НЕДЕЛИ ISO | |-------------------------+------+-----------+----- ---------+---------------+------------------| | 2016-01-02 23:39:20. 123 | 53 | 53 | 53 | 2015 | 2015 | +-------------------------+------+-----------+----- ---------+---------------+----+
Ниже показано использование функций DAYOFWEEK
и DAYOFWEEKISO
.
Параметр сеанса WEEK_START указывает, что неделя начинается в воскресенье.
ALTER SESSION SET WEEK_START = 7;ВЫБОР '2016-01-02T23:39:20.123-07:00'::TIMESTAMP AS tstamp, DAYOFWEEK(tstamp) КАК "ДЕНЬ НЕДЕЛИ", DAYOFWEEKISO(tstamp) КАК "ДЕНЬ НЕДЕЛИ ISO" ; +-------------------------+---------------+--------- --------+ | ТСТАМП | ДЕНЬ НЕДЕЛИ | ДЕНЬ НЕДЕЛИ ISO | |-------------------------+---------------+--------- --------| | 2016-01-02 23:39:20.123 | 7 | 6 | +-------------------------+---------------+--------- --------+
Ниже показано использование функций DAYOFWEEK
и DAYOFWEEKISO
.
Параметр сеанса WEEK_START указывает, что неделя начинается в понедельник.
ИЗМЕНИТЬ НАБОР СЕССИИ WEEK_START = 0;ВЫБОР '2016-01-02T23:39:20.123-07:00'::TIMESTAMP AS tstamp, DAYOFWEEK(tstamp) КАК "ДЕНЬ НЕДЕЛИ", DAYOFWEEKISO(tstamp) КАК "ДЕНЬ НЕДЕЛИ ISO" ; +-------------------------+---------------+--------- --------+ | ТСТАМП | ДЕНЬ НЕДЕЛИ | ДЕНЬ НЕДЕЛИ ISO | |-------------------------+---------------+--------- --------| | 2016-01-02 23:39:20.123 | 6 | 6 | +-------------------------+---------------+--------- --------+
Дополнительные примеры см. в разделе Использование дат и временных меток.
Более подробные примеры функций, связанных с неделей (DAYOFWEEK, WEEK, WEEKFYEAR, YEAROFWEEK и т. д.), см. в разделе «Недели календаря и дни недели».
SQL Server Функция даты, которая определяет диапазон дат на основе дня недели
Автор: Тим Форд | Комментарии (2) | Связанный: Еще > Даты
Проблема
Иногда я ловлю себя на том, что стряхиваю пыль со своего старого проявителя. кружку кофе и сел перед моим ноутбуком, чтобы немного заняться кодированием когда один из наших текущих разработчиков сталкивается с чем-то, что они не могут получить голову вокруг. Недавно это было в случае с хранимой процедурой, которую они пытаясь создать это, необходимое для возврата результатов для диапазона дат, основанного на день недели, а не конкретное число месяца.
Клиенту нужно было получить набор результатов на основе «с четверга по среду». период с прошлой недели», как было лаконично сказано. Если хранимая процедура всегда планировалось запускать в определенный день недели, это было бы легко вычислить, однако конечный пользователь должен иметь гибкость для запуска этого хранимая процедура в пятницу, субботу или воскресенье в зависимости от ситуации и разработчик не хотел заставлять пользователя вводить дату начала и окончания в чтобы смягчить плохие параметры, вызывающие неправильные отчеты. Генерация начала параметры даты и даты окончания стали проблемой, в которую я действительно вникал. я хотел создать повторно используемую кодовую базу, материализованную в виде определяемого пользователем как показано ниже.
Решение
Созданная мной функция использует несколько существующих системные функции, основанные на дате: DATEADD() и DATENAME().
- DATEADD() принимает три параметра: datepart, number, и date . Эта функция возвращает значение типа datetime на основе начальной даты. (параметр даты ) и количество добавленных или вычтенных приращений с этой даты (обозначенной параметрами datepart и number .) 903:30
- DATENAME(), с другой стороны, возвращает строку символов, которая означает значение datepart для заданной даты (передается как datepart и дата параметры соответственно.) Не глядя на код это может показаться немного запутанным:
Вот функция, которую я создал, которая использует обе эти системные функции.
CREATEFUNCTIONdbo.DAYSEARCH(@day_nameVARCHAR(9),@step_countINT,@directionsmallint) ВОЗВРАЩАЕТдата и время КАК НАЧИНАТЬ /* Возвращает дату на основе критериев поиска конкретного дня недели для определенного количества «шагов» вперед или назад. Например, «последняя среда» или «два четверга с сегодняшнего дня». @day_name=dayofweektofindie.Понедельник, вторник... @step_count=количество повторений назад за определенный день: -------->"1Последнийпонедельник"=1 -------->"3Thursdaysfromnow"=3 @направление: -------->-1ifPast -------->1ifFuture */ DECLARE@daysearchdatetime DECLARE@countersmallint DECLARE@hitssmallint DECLARE@day_name_calcVARCHAR(9) SELECT@counter=@направление ВЫБЕРИТЕ @ хиты = 0 ПОКА@хиты<@step_count НАЧИНАТЬ SELECT@day_name_calc=DATENAME(день недели,DATEADD(d,@counter,GETDATE())) IF@day_name_calc=@day_name НАЧИНАТЬ SELECT@hits=@hits+1 SELECT@daysearch=DATEADD(d,@counter,GETDATE()) КОНЕЦ SELECT@счетчик=(@счетчик+(1*@направление)) КОНЕЦ RETURN@daysearch КОНЕЦ
Пользовательская функция DAYSEARCH() требует трех параметров:
- @day_name, которое является названием дня, который вы ищете (например, «понедельник», «вторник» и т. д.)
- @step_count, означающее количество циклов вперед или назад, на которые вы при поиске (в прошлый понедельник потребуется значение 1, три понедельника назад потребуется требуется значение 3)
- @direction, который должен иметь одно из двух значений: -1 для поиска в обратном направлении. время или 1 для поиска в будущем.
С этого момента просто вопрос использования DATENAME() и DATEADD() функции в сочетании, чтобы вернуть значение функции DATENAME() для каждого день вперед или назад во времени (в зависимости от параметра @direction). Когда возвращается правильный день (результат функции DATENAME() равен параметр @day_name, предоставленный пользователем или кодом процедуры), записывается «попадание». Итерации продолжают выполняться до тех пор, пока количество «попаданий» не совпадет с @step_count. параметр функции DAYSEARCH(). Когда это происходит, функция возвращает value записывает дату, сгенерированную соответствующей функцией DATEADD(), и возвращает пользователю в качестве вывода функции.
Как только я создал DAYSEARCH(), я смог передать его разработчику для использования из хранимой процедуры, которую он создавал. Для того, чтобы обозначить предыдущий период времени с четверга по среду ему просто нужно было установить начало и конец значения в предложении WHERE его запроса способом, аналогичным упрощенному блоку кода показано ниже:
SELECTT1. поле1,T1.поле2,T1.поле3,T1.поле4 FROMtable1T1 WHERET1.start_date=dbo.DAYSEARCH('Четверг',2,-1) ANDT1.end_date=dbo.DAYSEARCH('Среда',1,-1)
Вот еще один пример, показывающий, как выглядит вывод, если мы хотим знать время сейчас, дату в четверг две недели назад и дату в среду прошлой недели.
SELECTGETDATE()ASTimeNow, dbo.DAYSEARCH('Четверг',2,-1)ASStartDate, dbo.DAYSEARCH('Среда',1,-1)ASendDate
Вот результат вышеуказанного запроса.
А вот и календарь с текущей датой ( TimeNow=2009-06-09 ), четверг двухнедельной давности ( StartDate = 2009-05-28 ) и среда прошлой недели ( EndDate=2009-06-03 ).
Следующие шаги
- Эта функция может не соответствовать вашим потребностям, но теперь вы можете увидеть, как вы можно использовать системную функцию для создания собственных пользовательских функций даты.
Об авторе
Тим Форд — старший администратор баз данных в MindBody.Посмотреть все мои советы
, вторник, 8 ноября 2011 г. — 10:23:26 — Кит | Вернуться к началу (15047) |
Эта формула, использующая DatePart внутри DateAdd, делает то же самое без необходимости зацикливания. ---------------------------------------------------------------------------- ------------------ Declare @EffDate date = '09NOV2011', -- введите дату вступления в силу Выберите EffDate = @EffDate, |
Среда, 28 октября 2009 г. |