如何在SQL Server中拆分虚线分隔的值

如何在SQL Server中拆分虚线分隔的值,sql,sql-server,Sql,Sql Server,我有一个保存在nvarchar类型中的日期,我想将日期、月份和年份拆分为单独的nvarchar变量(即三个变量)。日期如下所示:exposure\u date='2018-12-04',格式为yyyy-dd-mm 需要帮忙吗 我的整个项目都停留在这一点上。你可以在下面试试- select concat(cast(year(cast('2018-12-04' as date)) as varchar(4)),'-', cast(month(cast('2018-12-04' as date))

我有一个保存在
nvarchar
类型中的日期,我想将日期、月份和年份拆分为单独的
nvarchar
变量(即三个变量)。日期如下所示:
exposure\u date='2018-12-04'
,格式为
yyyy-dd-mm
需要帮忙吗

我的整个项目都停留在这一点上。

你可以在下面试试-

select  concat(cast(year(cast('2018-12-04' as date)) as varchar(4)),'-', 
cast(month(cast('2018-12-04' as date)) as varchar(2)), '-',
cast(day(cast('2018-12-04' as date)) as varchar(2)))
from tablename

您也可以尝试以下方法

Declare @myDate date 
select @myDate= Cast(substring('2011-29-12', 1, 4) 
+ '-' + substring('2011-29-12', 9, 2)
+ '-' + substring('2011-29-12', 6, 2)
as Date)   --YYYY-MM-DD

Select @myDate as DateTime,
           datename(day,@myDate) as Date,
           month(@myDate) as Month,
           datename(year,@myDate) as Year,
           Datename(weekday,@myDate) as DayName  
输出如下所示

DateTime    Date    Month   Year    DayName
--------------------------------------------
2011-29-12  29      12      2011    Thursday

如果您有固定格式,您可以找到实时演示

,然后您可以将此简单查询与
子字符串
方法结合使用:

select substring(dt, 1, 4) + '-' +
       substring(dt, 9, 2) + '-' +
       substring(dt, 6, 2) [YYYY-MM-DD]
from (values ('2018-31-12')) tbl(dt)
这里的“正确”答案是修复您的数据类型。存储数据时,请始终为所存储的数据选择适当的数据类型。对于日期(没有时间部分),正确的数据类型是
date
。如果要存储数字数据,请使用数字数据类型,例如
int
decimal
(n)varchar
不是一种“一刀切”的数据类型,使用它来存储具有专门为其设计的数据类型的数据几乎总是一个错误的选择。我将数据存储为
(n)varchar
,因为我需要特定格式的数据从来都不是借口;让您的表示层句柄显示格式,而不是RDBMS

因此,第一步是通过执行以下操作将日期的字符串表示形式
yyyy-dd-MM
更改为ISO格式
yyyyymmdd

UPDATE YourTable
SET exposure_date = LEFT(exposure_date,4) + RIGHT(exposure_date,2) + SUBSTRING(exposure_date,6,2);
现在有了明确的表示形式,您可以更改列的数据类型,而不必担心不正确的隐式强制转换或错误:

ALTER YourTable ALTER COLUMN exposure_date date;
最后,您可以将数据视为日期,并使用
DATEPART
函数:

SELECT DATEPART(YEAR,exposure_date) AS Exposure_Year,
       DATEPART(MONTH,exposure_date) AS Exposure_Month,
       DATEPART(DAY,exposure_date) AS Exposure_Day
FROM YourTable;

让我们直接转到主要问题,即您使用了错误的数据类型来存储日期,您应该将它们存储为
DATE
,这些数据类型存在是有原因的,您需要为您的列选择一个合适的数据类型

因此,您需要更改表并将列数据类型更改为
DATE
,而不是
NVARCHAR
数据类型

ALTER <Table Name Here>
ALTER COLUMN <Column Name Here> DATE;


日期和时间数据类型没有格式。如果您使用“格式”
yyyy-dd-MM
存储日期,这意味着您将它们存储为
varchar(10)
。很简单:不要。将日期按原样存储,即
日期
。如果随后将日期存储为正确的数据类型,则可以使用[
日期部分
]功能。这实际上是一个XY问题。您试图解决的问题是拆分字符串的不同部分以解决获取日期部分的问题(问题Y),然而,真正的问题是您使用了错误的数据类型(问题X),使用正确的数据类型使解决方案变得微不足道。“我有一个日期保存在
nvarchar
类型中”这是你的问题。日期应该存储为日期,而不是字符串。似乎我忘记了实际链接。哇。OP使用
varchar
存储日期,并且使用
yyyy-dd-MM
格式。只需使用
cast
就可以将值
'2018-12-04'
转换为日期
20181204
,这是不正确的。您是否检查过像2018-13-04这样的值,这将产生转换错误。@fa06非常感谢!真管用!如果我现在就想把他们干掉呢?我想将它们重新组合在一起,但我希望格式为yyyy-mm-dd,这意味着2018-12-04将成为2018-04-12,并将其存储在一个变量中。您可以使用concat()function@fa06当我添加此行时,选择CONCAT(年、月、日);SQL不识别yr、mon和dy变量OP特别声明它们的格式为
yyyy-dd-MM
,而不是
yyy-MM-dd
。非常感谢!真管用!如果我现在就想把他们干掉呢?我想将它们重新组合在一起,但我希望格式为yyyy-mm-dd,这意味着2018-12-04将成为2018-04-12,并将其存储在variable@HoussemTimoumi请参阅更新的答案,如果答案对您有帮助,您应该接受它(左侧的绿色复选标记),并可以选择向上投票。
SELECT YEAR(<Column Name Here>) TheYear,
       MONTH(<Column Name Here>) TheMonth,
       DAY(<Column Name Here>) TheDay
FROM <Table Name Here>
CREATE TABLE Dates(
  StrDate NVARCHAR(10)
);

INSERT INTO Dates VALUES
(N'2018-12-04'),
(N'Invalid');

SELECT LEFT(StrDate, 4) StrYear,
       SUBSTRING(StrDate, 6, 2) StrMonth,
       RIGHT(StrDate, 2) StrDay
FROM Dates;
SELECT YEAR(StrDate) StrYear,
       MONTH(StrDate) StrMonth,
       DAY(StrDate) StrDay
FROM (
       SELECT TRY_CAST(StrDate AS DATE) StrDate
       FROM Dates
     )T