Преобразование названия дня в его целочисленное представление - PullRequest
5 голосов
/ 23 декабря 2008

На сервере SQL вы можете использовать функцию DATENAME, чтобы получить день недели в виде строки

declare @date datetime
set @date = '12/16/08'
select datename(dw, @date)

, который возвращает «вторник»

и вы можете использовать функцию DATEPART, чтобы получить день недели в виде целого числа

declare @date datetime
set @date = '12/16/08'
select datepart(dw, @date)

Что возвращает 3

Но скажем, у меня есть varchar, который содержит строку "Tuesday", и я хочу преобразовать ее в целочисленное представление 3. Конечно, я мог бы записать преобразование без особых хлопот, но я бы скорее использовал встроенный -в функции. Существует ли такая функция?

Ответы [ 9 ]

11 голосов
/ 23 декабря 2008

к сожалению, нет встроенной функции, но вы можете создать свою собственную так:


CREATE FUNCTION dbo.WeekDay(@DayOfWeek Varchar(9))
RETURNS INT
            AS
    BEGIN
    DECLARE @iDayofWeek INT
    SELECT @iDayofWeek = CASE @DayOfWeek
                    WHEN 'Sunday' THEN 1
                    WHEN 'Monday' THEN 2
                    WHEN 'Tuesday' THEN 3
                    WHEN 'Wednesday' THEN 4
                    WHEN 'Thursday' THEN 5
                    WHEN 'Friday' THEN 6
                    WHEN 'Saturday' THEN 7
        END
    RETURN (@iDayofWeek)
    END
GO
10 голосов
/ 23 декабря 2008

Вместо того, чтобы писать функцию, вы должны создать таблицу дней недели с описанием и числовым значением. Затем вы можете просто присоединиться к таблице, чтобы получить числовое значение.

И если дни хранятся несколькими способами (вероятно, в системе с символами), вы можете поместить все варианты в таблицу, поэтому значения TUE, вторник, вторник будут отображаться в одно и то же целое число.

2 голосов
/ 16 декабря 2014

Вот грязная альтернатива, которую я использую, если не запускаю ее для массивного набора данных.

    Select CHARINDEX(SUBSTRING('Thursday',1,3), 'MONTUEWEDTHUFRISATSUN') / 3 + 1

Просто замените четверг на выбранный вами день или переменную.

Как это работает: SUBSTRING ('Thursday', 1,3) в основном создает Thu, затем charindex определяет положение thu в строке, равной 10. Затем мы делим 10 на длину наших дневных слов, равную 3, что равно 3, и потому что я хочу

Понедельник равен 1 Вторник равен 2 Среда равняется 3 Четверг равен 4

Я добавляю 1 в конец

поэтому результат равен 4.

Надеюсь, это кому-то поможет, но я согласен, что, возможно, это не лучшее решение.

Примечание: Вы также можете заказать набор результатов по номеру дня, используя его следующим образом:

SELECT ID,DayNamesColumn from mytable ORDER BY CHARINDEX(SUBSTRING(DayNamesColumn ,1,3), 'MONTUEWEDTHUFRISATSUN') / 3 + 1
2 голосов
/ 03 апреля 2014

Хорошо, 6 лет спустя и несколько версий SQL Server, но встроенной функции для этого по-прежнему нет (насколько я знаю). Не уверен, что что-нибудь сделает для этого.

Я применил аналогичный подход к @RussBradberry, только что с IF заявлениями.

CREATE FUNCTION dbo.WeekDayInt (@DayOfWeekName VARCHAR(10))
RETURNS INT
AS
    BEGIN
        DECLARE @DayWeekNumber INT
        IF @DayOfWeekName = 'Sunday'    SET @DayWeekNumber = 1
        IF @DayOfWeekName = 'Monday'    SET @DayWeekNumber = 2
        IF @DayOfWeekName = 'Tuesday'   SET @DayWeekNumber = 3
        IF @DayOfWeekName = 'Wednesday' SET @DayWeekNumber = 4
        IF @DayOfWeekName = 'Thursday'  SET @DayWeekNumber = 5
        IF @DayOfWeekName = 'Friday'    SET @DayWeekNumber = 6
        IF @DayOfWeekName = 'Saturday'  SET @DayWeekNumber = 7;
        RETURN (@DayWeekNumber)
    END

или в качестве альтернативы это может быть сделано таким образом, что может быть немного быстрее, потому что он вернет значение, как только будет найдено совпадение, и не будет пытаться оценить другие значения.

CREATE FUNCTION dbo.WeekDayInt (@DayOfWeekName VARCHAR(10))
RETURNS INT
AS
    BEGIN
        IF @DayOfWeekName = 'Sunday'    RETURN 1
        IF @DayOfWeekName = 'Monday'    RETURN 2
        IF @DayOfWeekName = 'Tuesday'   RETURN 3
        IF @DayOfWeekName = 'Wednesday' RETURN 4
        IF @DayOfWeekName = 'Thursday'  RETURN 5
        IF @DayOfWeekName = 'Friday'    RETURN 6
        IF @DayOfWeekName = 'Saturday'  RETURN 7;
        RETURN 0;
    END
1 голос
/ 16 декабря 2016

Вы можете использовать следующий выбор, чтобы получить порядковый номер дня недели iso даты 2017-12-15 относительно (например, независимо от) текущей настройки @@ datefirst, которая определяет первый день недели. Например. установите datefirst = 1 для понедельника.

select
  w.weekday_id_iso8601,
  w.weekday_id_datepart,
  w.weekday_name
from (
       values
         (7, 'Monday'),
         (8, 'Tuesday'),
         (9, 'Wednesday'),
         (10, 'Thursday'),
         (11, 'Friday'),
         (12, 'Saturday'),
         (13, 'Sunday'))
     t(weekday_id, weekday_name)
cross apply (
  select
    t.weekday_id - 6 weekday_id_iso8601,
    (t.weekday_id - @@datefirst + 1) % 7 + 1 weekday_id_datepart,
    t.weekday_name
) w
where w.weekday_id_datepart = datepart(weekday, '2017-12-15')
0 голосов
/ 24 августа 2016

В SQL 2014 вы можете использовать:

SELECT DATEPART (DW, GetDate ()) Возвращает день недели как целое число.

0 голосов
/ 22 октября 2015

Где DayID - целое число от 1 до 7.

Добавьте DayID к некоторой базовой дате, такой как 1899-12-31. (Если воскресенье - первый день недели, используйте начальную дату 1899-12-30)

1900-01-01 - понедельник, 1900-01-02 - вторник и т. Д.

Таким образом:

select DayID, 
       datename( weekday, dateadd( day, DayID, '18991231' ) ) 
0 голосов
/ 23 декабря 2008

Это может не служить практической цели, но я подумал, что пойму это просто для удовольствия. :) Следующие работы.

Помните, что при использовании DATEPART или DATENAME значение @@ DATEFIRST важно и может изменить ваши результаты. Найдите SET DATEFIRST в онлайн-справке.

DECLARE
    @date_name AS VARCHAR(20)

SET @date_name = 'Monday'

SELECT
    DATEPART(dw, my_date)
FROM
    (
    SELECT CAST('1900-01-01' AS DATETIME) AS my_date UNION
    SELECT CAST('1900-01-02' AS DATETIME) AS my_date UNION
    SELECT CAST('1900-01-03' AS DATETIME) AS my_date UNION
    SELECT CAST('1900-01-04' AS DATETIME) AS my_date UNION
    SELECT CAST('1900-01-05' AS DATETIME) AS my_date UNION
    SELECT CAST('1900-01-06' AS DATETIME) AS my_date UNION
    SELECT CAST('1900-01-07' AS DATETIME) AS my_date
    ) AS My_Dates
WHERE
    DATENAME(dw, my_date) = @date_name
0 голосов
/ 23 декабря 2008

Я не согласен с ответом о добавлении справочной таблицы, поскольку в этом случае значения ограничены и никогда не изменятся. Соединение с таблицей поиска просто добавит стоимость.

ИМХО; поскольку у вас ограниченные значения, я бы просто использовал выражение case в своих представлениях. Это не красиво, но, вероятно, это самый быстрый способ сделать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...