Как показать название дня в SQL Server? - PullRequest
7 голосов
/ 26 апреля 2019

У меня есть запрос на сервере SQL

Я хочу отобразить, как показано ниже:

CDATE      | CDAY
2019-04-01 | Monday
2019-04-02 | Tuesday
...        | ......
2019-04-30 | Tuesday

Но я обнаружил ошибку, как показано ниже:

Преобразованиеошибка при преобразовании даты и / или времени из символьной строки.

Пожалуйста, если кто-то может помочь

DECLARE @V_DATE DATE = GETDATE()

;WITH CTE_DATE AS (
        SELECT  DATEADD(dd,-(DAY(@V_DATE)-1),@V_DATE) CDATE,
        DATENAME(dw, CONVERT(varchar, DATEADD(dd,-(DAY(@V_DATE)-1),@V_DATE))) CDAY
        UNION ALL
        SELECT  DATEADD(dd,1,CDATE),
        DATENAME(dw, CONVERT(varchar, DATEADD(dw,1,CDAY)))
        FROM    CTE_DATE
        WHERE   DATEADD(dd,1,CDATE) <= DATEADD(dd,-(DAY(DATEADD(mm,1,CDATE))),DATEADD(mm,1,CDATE))

    )
    SELECT * FROM CTE_DATE

Ответы [ 5 ]

2 голосов
/ 26 апреля 2019

Не нужно CONVERT даты.Используйте функцию FORMAT.И используйте EOMONTH функцию:

DECLARE @V_DATE DATE = DATEADD(DAY, 1, EOMONTH(GETDATE(), -1));
WITH CTE_DATE AS (
    SELECT @V_DATE CDATE

    UNION ALL

    SELECT DATEADD(dd, 1, CDATE)
    FROM   CTE_DATE
    WHERE  DATEADD(dd, 1, CDATE) <= EOMONTH(@V_DATE)
)
SELECT CDATE, FORMAT(CDATE, 'dddd') AS CDAY, FORMAT(CDATE, 'ddd') AS CDAYSHORT
FROM CTE_DATE
2 голосов
/ 26 апреля 2019

Нет необходимости фиксировать названия дней внутри CTE, используйте его только для генерации дат.

DECLARE @V_DATE DATE = GETDATE()

WITH CTE_DATE AS
(
    SELECT  DATEADD(day ,-(DAY(@V_DATE)-1),@V_DATE) as CDATE
    UNION ALL
    SELECT  DATEADD(day, 1, CDATE)
    FROM    CTE_DATE
    WHERE   DATEADD(day, 1, CDATE) <= DATEADD(day, -(DAY(DATEADD(month, 1, CDATE))), DATEADD(month, 1, CDATE))
)
SELECT CDATE, DATENAME(dw, CDATE) FROM CTE_DATE
2 голосов
/ 26 апреля 2019

Вы можете в ближайшее время использовать функцию datename() ( используется с v.2008 )

  select datename( weekday, getdate() ) as day

  day
  ------
  Friday  -- > "for today(2019-04-26)"

Демо

или как в вашем случае:

with t(cdate) as
(
 select '2019-04-01' union all
 select '2019-04-02' union all
 select '2019-04-30'    
)    
select cdate, datename( weekday, cdate  ) as cday
  from t;

+----------+-------+
| cdate    | cday  |
+----------+-------+
|2019-04-01|Monday |
|2019-04-02|Tuesday|
|2019-04-30|Tuesday|
+----------+-------+
2 голосов
/ 26 апреля 2019

Ваша проблема:

DATENAME(dw, DATEADD(dw, 1, CDAY))

Я думаю, вы намереваетесь:

DATENAME(dw, DATEADD(dw, 1, CDATE))

Я бы написал CTE как:

WITH CTE_DATE AS (
        SELECT  DATEADD(day ,-(DAY(@V_DATE)-1),@V_DATE) as CDATE, 
                DATENAME(dw, DATEADD(day, -(DAY(@V_DATE) - 1), @V_DATE)) as CDAY
        UNION ALL
        SELECT  DATEADD(day, 1, CDATE),
                DATENAME(dw, DATEADD(dw, 1, CDATE))
        FROM    CTE_DATE
        WHERE   DATEADD(day, 1, CDATE) <= DATEADD(day, -(DAY(DATEADD(month, 1, CDATE))), DATEADD(month, 1, CDATE))

    )
    SELECT *
    FROM CTE_DATE;

Здесь - это db <> скрипка.

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

2 голосов
/ 26 апреля 2019

Нет необходимости конвертировать в varchar, чтобы получить день недели.

 UNION ALL
        SELECT  DATEADD(dd,1,CDATE),
        DATENAME(dw, CONVERT(varchar, DATEADD(dw,1,CDAY))) -- No need to convert to varchar in order to get weekday.
        FROM    CTE_DATE
        WHERE   DATEADD(dd,1,CDATE) <= DATEADD(dd,-(DAY(DATEADD(mm,1,CDATE))),DATEADD(mm,1,CDATE))

вы можете получить его напрямую с помощью функции datename.

  DECLARE @V_DATE DATE = GETDATE()

    ;WITH CTE_DATE AS (
            SELECT  DATEADD(dd,-(DAY(@V_DATE)-1),@V_DATE) CDATE,
                    DATENAME(dw, CONVERT(varchar, DATEADD(dd,-(DAY(@V_DATE)-1),@V_DATE))) CDAY
            UNION ALL
            SELECT  DATEADD(dd,1,CDATE),
                    DATENAME(dw,  DATEADD(dd,1,CDATE)) -- modified 
            FROM    CTE_DATE
            WHERE   DATEADD(dd,1,CDATE) <= DATEADD(dd,-(DAY(DATEADD(mm,1,CDATE))),DATEADD(mm,1,CDATE))

        )
        SELECT * FROM CTE_DATE
...