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() выдает один из своих параметров по номеру соответствующий первому параметру, т.е. в зависимости от дня недели он выдаст один из столбцов, который мы и проверяем на заполненность.

6=66 и проверяем логическими операциями типа 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 буквы дня недели, поэтому берем подстроку из первых двух букв).

1

Зарегистрируйтесь или войдите

Регистрация через 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

ГОД* / ДЕНЬ* / НЕДЕЛЯ* / МЕСЯЦ / КВАРТАЛ

Категории:

Функции даты и времени

Извлекает соответствующую часть даты из даты или метки времени.

Эти функции являются альтернативой использованию функции 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, делает то же самое без необходимости зацикливания.

---------------------------------------------------------------------------- ------------------
-- Возвращает дату DayOfWeek относительно введенной даты
-- Пример: четверг двухнедельной давности или понедельник в конце следующего месяца
-------------------------------------------------- ------------------
УСТАНОВИТЬ ДАТУПЕРВОЙ 7; -- SQL Server по умолчанию 7

Declare @EffDate    date       = '09NOV2011', -- введите дату вступления в силу
        @DayName    varchar(9) = 'MON', -- диапазон с понедельника по воскресенье
        @WeekOffset int        = 0  -- количество недель смещения; отрицательный для прошлого; позитив на будущее; ноль для текущей недели

Выберите EffDate     = @EffDate,
       [DayName]   = @DayName,
       WeekOffset  = @WeekOffset,
       [DateFirst] = @@DATEFIRST,
       [DayOfWeek] = DatePart(день недели, @EffDate),
       [Output] = DateAdd(day, - @@DATEFIRST + 7 * ( @WeekOffset + 1 ) +
                  CASE @DayName WHEN 'MON' Then 2
                                 КОГДА 'ВТ' Тогда 3
                               КОГДА 'СР' Тогда 4
                                КОГДА ' ЧТ' Тогда 5
                              КОГДА 'ПТ' Тогда 6
                                КОГДА 'СБ' Тогда 7
                               WHEN 'SUN' Then 1
                  END
                  - DatePart(weekday,@EffDate), @EffDate)


Среда, 28 октября 2009 г.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *