将第1天的YYYYMM字符串转换为日期YYYY-MM-DD

时间:2019-04-16 09:30:45

标签: sql sql-server

我在表格中有 Startmonth 列,该日期是这样的: YYYYMM ,所以 201801 201707 等。

我希望在自己的视图中创建此列,但希望将其转换为日期,例如 YYYY-MM-DD ,并将日期作为月份的第一天,所以** 201801> 2018-01-01和201707> 2017-07-01。 **

我不断收到错误消息:

  

从字符转换日期和/或时间时转换失败   字符串。

有人可以帮我吗?

我尝试过:

select convert (DATE, concat (s.StartMonth,'01'), 102) as SubscriptionStart

from incident i

left join imcustomerid cid on i.accountid = cid.accountid
left join billing_subscription s on cid.imcustomerid = s.idcustomer
left join billing_subscriptiontype st on s.idsubscriptiontype = st.id

3 个答案:

答案 0 :(得分:2)

尝试使用

select convert (DATE, concat (s.StartMonth,'01'), 112) as SubscriptionStart

select cast(concat (s.StartMonth,'01') as date) as SubscriptionStart

CAST and CONVERT (Transact-SQL)

我认为最好在这里使用TRY_CONVERT,如@Larnu所述:

select try_convert(date, s.StartMonth+'01', 112) as SubscriptionStart

+而不是CONCAT正确转换NULL值。

答案 1 :(得分:1)

问题是您正在使用字符串在表上进行左连接,这意味着如果incident行没有匹配的行,则转换有时会为空,然后转换失败

这是解决此问题的一种方法

SELECT CASE WHEN s.StartMonth IS NOT NULL THEN convert(DATE, concat (s.StartMonth,'01'), 112)
       ELSE null -- Or return some default value, otherwise this row can be removed
       END  as SubscriptionStart
FROM incident i
LEFT JOIN imcustomerid cid ON i.accountid = cid.accountid
LEFT JOIN billing_subscription s ON cid.imcustomerid = s.idcustomer
LEFT JOIN billing_subscriptiontype st ON s.idsubscriptiontype = st.id

另一种方法是使用TRY_CONVERT代替另一个答案中提到的CASE,这取决于您要在null时返回什么。

答案 2 :(得分:0)

我认为最清晰的方法是datefromparts()

select datefromparts(year(s.StartMonth),
                     month(s.StartMonth),
                     1) as SubscriptionStart

更传统的方法是减去天数:

select dateadd(day,
               (1 - day(s.StartMonth)),
               s.StartMonth
              ) as SubscriptionStart

为此,我建议将日期转换为字符串。绝对没有必要,日期也不同于字符串。