我被交给一个表,其中Date列被加载为nvarchar(50)。
我或多或少想通过将其转换为日期时间。
select convert(datetime, Date_Time_In, 101)
FROM [DB].[dbo].[table]
但我遇到一个问题,它不会删除列的时间部分。另外,我将如何将其放回表中,或者只是使用特定的sql代码在表中进行转换。该数据库有大约3000万行和160多列。
最终目标是尝试对我的数据进行排序,因为我尝试使用以下内容:
SELECT *
FROM [DB].[dbo].[table]
WHERE Date_Time_In between '1/1/2019 01:00:00 PM' and '4/1/2019 01:00:00 PM'
它只是查询所有日期。
*转换为日期时间格式101时的查询
如果您不需要时间部分,请使用
CONVERT(datetime, Date_Time_In, 111)
要替换原始列,请创建一个新列,使用转换日期填充该列,重命名原始列,将原始名称分配给新列。
如果您将日期存储为字符串,则日期函数将不起作用。完全停止。你有文字,而不是日期。
为了创建你有日期以便你可以使用日期函数的错觉,你将不得不做一些像这样的恐怖事件(由于函数调用,因为WHERE
谓词是非SARGable,所以会永远运行):
SELECT
*
FROM
[DB].[dbo].[table]
WHERE
CONVERT(DATETIME, Date_Time_In, 101)
BETWEEN '1/1/2019 01:00:00 PM' AND '4/1/2019 01:00:00 PM';
更好的解决方案是:
1)修复当前列上的数据类型(我知道;遗留系统,相当多的记录,等等,这不太可能,但如果你能做到,WOO HOO!)
要么
2)将列号161添加为实际为DATETIME
的持久计算列
ALTER TABLE [DB].[dbo].[table]
ADD DateTimeIn AS TRY_PARSE(Date_Time_In AS DATETIME) PERSISTED;
简短的回答是你需要将比较的两边都投射到相同的日期类型。
答案很长,你需要修复该表的底层结构。数据类型非常重要,将所有内容存储为“字符串”只会在有人想要报告该数据时引发问题。我希望以下示例有助于说明这一点。首先看看时间戳在被转换或转换为不同类型时会发生什么。然后看看在比较中使用这些类型会发生什么。更好的方法是将时间戳存储为NVARCHAR(50),而不是存储为DATETIME,DATETIME2或DATE,具体取决于您需要的准确度。
SELECT CAST('1/1/2019 01:00:00 PM' AS DATETIME) betweenStart,
CAST('4/1/2019 01:00:00 PM' AS DATETIME) betweenEnd
SELECT CONVERT(DATETIME, '1/1/2019 01:00:00 PM', 101) betweenStart,
CONVERT(DATETIME, '4/1/2019 01:00:00 PM', 101) betweenEnd
-- betweenStart betweenEnd
-- 2019-01-01 13:00:00.000 2019-04-01 13:00:00.000
SELECT CAST('1/1/2019 01:00:00 PM' AS DATETIME2) betweenStart,
CAST('4/1/2019 01:00:00 PM' AS DATETIME2) betweenEnd
SELECT CONVERT(DATETIME2, '1/1/2019 01:00:00 PM', 101) betweenStart,
CONVERT(DATETIME2, '4/1/2019 01:00:00 PM', 101) betweenEnd
-- betweenStart betweenEnd
-- 2019-01-01 13:00:00.0000000 2019-04-01 13:00:00.0000000
SELECT CAST('1/1/2019 01:00:00 PM' AS DATE) betweenStart,
CAST('4/1/2019 01:00:00 PM' AS DATE) betweenEnd
SELECT CONVERT(DATE, '1/1/2019 01:00:00 PM', 101) betweenStart,
CONVERT(DATE, '4/1/2019 01:00:00 PM', 101) betweenEnd
-- betweenStart betweenEnd
-- 2019-01-01 2019-04-01
IF OBJECT_ID('tempdb..#t') IS NOT NULL
BEGIN
DROP TABLE #t
END
CREATE TABLE #t(
myIdCol INT IDENTITY(1,1),
Date_Time_In NVARCHAR(50)
)
INSERT INTO #t
VALUES('10/24/2018 12:52:10 PM'),
('10/26/2018 3:53:45 PM'),
('10/26/2018 3:53:45 PM'),
('1/1/2019 3:53:45 PM'),
('4/1/2019 12:59:00 PM'),
('4/1/2019 01:00:01 PM')
SELECT * FROM #t WHERE Date_Time_In BETWEEN '1/1/2019 01:00:00 PM' AND '4/1/2019
01:00:00 PM'
-- myIdCol Date_Time_In
-- 1 10/24/2018 12:52:10 PM
-- 2 10/26/2018 3:53:45 PM
-- 3 10/26/2018 3:53:45 PM
-- 4 1/1/2019 3:53:45 PM
SELECT *
FROM #t
WHERE CAST(Date_Time_In AS DATETIME) BETWEEN
CAST('1/1/2019 01:00:00 PM' AS DATETIME)
AND
CAST('4/1/2019 01:00:00 PM' AS DATETIME)
-- myIdCol Date_Time_In
-- 4 1/1/2019 3:53:45 PM
-- 5 4/1/2019 12:59:00 PM
SELECT *
FROM #t
WHERE CAST(Date_Time_In AS DATETIME2) BETWEEN
CAST('1/1/2019 01:00:00 PM' AS DATETIME2)
AND
CAST('4/1/2019 01:00:00 PM' AS DATETIME2)
-- myIdCol Date_Time_In
-- 4 1/1/2019 3:53:45 PM
-- 5 4/1/2019 12:59:00 PM
SELECT *
FROM #t
WHERE CAST(Date_Time_In AS DATE) BETWEEN
CAST('1/1/2019 01:00:00 PM' AS DATE)
AND
CAST('4/1/2019 01:00:00 PM' AS DATE)
-- myIdCol Date_Time_In
-- 4 1/1/2019 3:53:45 PM
-- 5 4/1/2019 12:59:00 PM
-- 6 4/1/2019 01:00:01 PM