将 varchar 转换为缺少时间的日期时间时,按结果排序超出范围
Order by results are out-of-range when converting varchar to datetime with missing time
我在 log-db 中有一个 varchar
行,通常看起来像 17.09.2020 00:00:01
我可以 CAST()
它到 datetime
并按它排序没有问题,例如这个简化的查询:
SELECT CAST(my_date_and_time AS datetime)
FROM my_table
ORDER BY CAST(my_date_and_time AS datetime) DESC
现在的问题是,今晚我在 00:00:00 处得到了一个日志条目,并且日志脚本或数据库从 varchar
字段中截断了时间,所以现在它只包含 17.09.2020
而不是 17.09.2020 00:00:00
。
当我尝试将其转换为 datetime
时,会出现超出范围的错误,可能是因为缺少时间部分?
不幸的是,我无法访问日志脚本来更改它。
那么有什么方法可以将其转换为查询中可用的格式吗?
编辑: 下面是 my_date_and_time 行的示例:
|---------------------|
| my_date_and_time |
|---------------------|
| 17.09.2020 05:29:53 |
|---------------------|
| 17.09.2020 00:02:11 |
|---------------------|
| 17.09.2020 |
|---------------------|
| 16.09.2020 23:59:38 |
|---------------------|
| 16.09.2020 23:59:18 |
|---------------------|
EDIT2: 通过进一步测试,我能够进一步缩小错误范围。这不是因为最初假设的时间戳没有时间信息。该问题实际上影响了不合规的记录。
这些数据记录月份前面少了0,年份后面多了一个点
例如16.9.2020. 14:22:23
我差点把编程这个的人的脑袋扯下来..
有没有什么办法可以通过查询得到正确的值呢?
对造成的误解深表歉意,并感谢迄今为止为解决问题做出贡献的所有人
正如我在评论中提到的,您真的应该修复数据类型。
如果您的所有日期 都是 格式 dd.MM.yyyy hh:mm:ss
那么您可以使用 CONVERT
和样式代码来转换它们,而不管设置如何:
SELECT TRY_CONVERT(datetime,Your_varchar,103)
FROM dbo.YourTable;
如果有 return NULL
它们要么具有值 NULL
,要么无法转换。
但回到修复您的数据。
首先,让我们在一个新专栏中这样做:
ALTER TABLE dbo.YourTable ADD Actual_date_and_Time datetime NULL
现在我们可以 UPDATE
通过覆盖值来 UPDATE
该值:
UPDATE dbo.YourTable
SET Actual_date_and_Time = TRY_CONVERT(datetime,Varchar_Date_and_time,103);
然后您可以查询实际的 datetime
列。
然后您可以查看您的新数据,看看是否有问题,并进行修改:
SELECT Varchar_Date_and_time
FROM dbo.YourTable
WHERE Varchar_Date_and_time IS NOT NULL
AND Actual_date_and_Time;
然后,最后,您可以 DROP
旧列并重命名新列(如果需要):
ALTER TABLE dbo.YourTable DROP COLUMN Varchar_Date_and_time;
EXEC sys.sp_rename N'dbo.YourTable.Actual_date_and_Time',N'Varchar_Date_and_time','COLUMN';
让我们试试 convert
函数 (Date and Time Conversions Using SQL Server):
declare @my_date_and_time varchar(19) = '17.09.2020 00:00:01';
select convert(date, @my_date_and_time, 104)
或尝试将 dateformat
设置为 dmy
(day/month/year):
set dateformat dmy
declare @my_date_and_time varchar(19) = '17.09.2020 00:00:01';
select cast(@my_date_and_time as date)
我在 log-db 中有一个 varchar
行,通常看起来像 17.09.2020 00:00:01
我可以 CAST()
它到 datetime
并按它排序没有问题,例如这个简化的查询:
SELECT CAST(my_date_and_time AS datetime)
FROM my_table
ORDER BY CAST(my_date_and_time AS datetime) DESC
现在的问题是,今晚我在 00:00:00 处得到了一个日志条目,并且日志脚本或数据库从 varchar
字段中截断了时间,所以现在它只包含 17.09.2020
而不是 17.09.2020 00:00:00
。
当我尝试将其转换为 datetime
时,会出现超出范围的错误,可能是因为缺少时间部分?
不幸的是,我无法访问日志脚本来更改它。 那么有什么方法可以将其转换为查询中可用的格式吗?
编辑: 下面是 my_date_and_time 行的示例:
|---------------------|
| my_date_and_time |
|---------------------|
| 17.09.2020 05:29:53 |
|---------------------|
| 17.09.2020 00:02:11 |
|---------------------|
| 17.09.2020 |
|---------------------|
| 16.09.2020 23:59:38 |
|---------------------|
| 16.09.2020 23:59:18 |
|---------------------|
EDIT2: 通过进一步测试,我能够进一步缩小错误范围。这不是因为最初假设的时间戳没有时间信息。该问题实际上影响了不合规的记录。
这些数据记录月份前面少了0,年份后面多了一个点
例如16.9.2020. 14:22:23
我差点把编程这个的人的脑袋扯下来..
有没有什么办法可以通过查询得到正确的值呢?
对造成的误解深表歉意,并感谢迄今为止为解决问题做出贡献的所有人
正如我在评论中提到的,您真的应该修复数据类型。
如果您的所有日期 都是 格式 dd.MM.yyyy hh:mm:ss
那么您可以使用 CONVERT
和样式代码来转换它们,而不管设置如何:
SELECT TRY_CONVERT(datetime,Your_varchar,103)
FROM dbo.YourTable;
如果有 return NULL
它们要么具有值 NULL
,要么无法转换。
但回到修复您的数据。
首先,让我们在一个新专栏中这样做:
ALTER TABLE dbo.YourTable ADD Actual_date_and_Time datetime NULL
现在我们可以 UPDATE
通过覆盖值来 UPDATE
该值:
UPDATE dbo.YourTable
SET Actual_date_and_Time = TRY_CONVERT(datetime,Varchar_Date_and_time,103);
然后您可以查询实际的 datetime
列。
然后您可以查看您的新数据,看看是否有问题,并进行修改:
SELECT Varchar_Date_and_time
FROM dbo.YourTable
WHERE Varchar_Date_and_time IS NOT NULL
AND Actual_date_and_Time;
然后,最后,您可以 DROP
旧列并重命名新列(如果需要):
ALTER TABLE dbo.YourTable DROP COLUMN Varchar_Date_and_time;
EXEC sys.sp_rename N'dbo.YourTable.Actual_date_and_Time',N'Varchar_Date_and_time','COLUMN';
让我们试试 convert
函数 (Date and Time Conversions Using SQL Server):
declare @my_date_and_time varchar(19) = '17.09.2020 00:00:01';
select convert(date, @my_date_and_time, 104)
或尝试将 dateformat
设置为 dmy
(day/month/year):
set dateformat dmy
declare @my_date_and_time varchar(19) = '17.09.2020 00:00:01';
select cast(@my_date_and_time as date)