好吧,我知道我的许多问题都是基于日期格式的,但这是我的问题。我正在处理一个字段,我们称之为它ABCTIME
,它以数字格式保存并显示为20110517151750
ie 2011-05-17:15:17:50
。我需要能够将其转换为日期,或者datetime
我可以使用 adatediff
来显示大于或 = 到今天日期 ( GETDATE
) 的所有记录。另外,我无法更改表格的格式。任何帮助将不胜感激。谢谢 -
编辑 - 我需要显示比今天日期 1 年或更长时间的所有记录。
好吧,我知道我的许多问题都是基于日期格式的,但这是我的问题。我正在处理一个字段,我们称之为它ABCTIME
,它以数字格式保存并显示为20110517151750
ie 2011-05-17:15:17:50
。我需要能够将其转换为日期,或者datetime
我可以使用 adatediff
来显示大于或 = 到今天日期 ( GETDATE
) 的所有记录。另外,我无法更改表格的格式。任何帮助将不胜感激。谢谢 -
编辑 - 我需要显示比今天日期 1 年或更长时间的所有记录。
将 getdate() 转换为 YYYYMMDDXXXXXX 以过滤大于或 = 到今天的效率要高得多,而不是转换您的数据以适应该条件。
编辑- 显示比今天日期 1 年或更长时间的所有记录
SELECT
*
FROM your_table
WHERE yyyymmddxxxxxx >= cast( convert(varchar, dateadd(YEAR,1,getdate()) ,112) AS bigint) * 1000000
您的样本在 2012 年之后没有任何内容,因此我将其中一个更改为 2015 年,结果如下:
CREATE TABLE sample_data
([Case] int, [Service] varchar(13), [DateInt] bigint)
;
INSERT INTO sample_data
([Case], [Service], [DateInt])
VALUES
(1, 'CHAMP VA', 20120928073334),
(2, 'MACSIS-MH POS', 20120927103950),
(3, 'MACSIS-MH POS', 20150927084716)
;
**Query 1**:
--YYYYMMDDXXXXXX
SELECT
DateInt
, convert(date,convert(varchar,DateInt / 1000000),112) as_date
, DateInt / 1000000 as_int_yyymmdd
FROM sample_data
WHERE DateInt >= cast( convert(varchar, dateadd(YEAR,1,getdate()) ,112) AS bigint) * 1000000
**[Results][2]**:
| DATEINT | AS_DATE | AS_INT_YYYMMDD |
|----------------|------------|----------------|
| 20150927084716 | 2015-09-27 | 20150927 |
您可以像这样创建函数:
CREATE FUNCTION udf_convert_int_date (@date_in INT)
RETURNS datetime
AS
BEGIN
DECLARE @date_out datetime
SET @date_out = CONVERT(datetime, CAST(@date_in AS CHAR(8)), 101)
RETURN @date_out
END
可以查询当前格式的日期。我不明白你为什么需要重新格式化日期。如果今天的日期减去 1 年是 2012 年 12 月 31 日 (20121231000000),则返回 ABCTIME >= 20121231000000 的所有记录。
它可能不漂亮,但是如果这始终是每个部分的固定格式和字符,您可以简单地使用子字符串或类似函数将其分解吗?在 SQL Server 中将日期转换为 120 格式 (yyyy-mm-dd hh:mi:ss) 这将类似于:
SELECT
-- 20110517151750 to 2011-05-17 15:17:50
SUBSTRING('20110517151750', 1, 4) AS Year,
SUBSTRING('20110517151750', 5, 2) AS Month,
SUBSTRING('20110517151750', 7, 2) AS Day,
SUBSTRING('20110517151750', 9, 2) AS Hour,
SUBSTRING('20110517151750', 11, 2) AS Minute,
SUBSTRING('20110517151750', 13, 2) AS Second,
CONVERT(datetime, SUBSTRING('20110517151750', 1, 4) + '-' + SUBSTRING('20110517151750', 5, 2) + '-' + SUBSTRING('20110517151750', 7, 2) + ' ' + SUBSTRING('20110517151750', 9, 2) + ':' + SUBSTRING('20110517151750', 11, 2) + ':' + SUBSTRING('20110517151750', 13, 2), 120) AS ParsedDate
FROM ...
如果您使用的是 SQLServer 2008 及更高版本,它现在有一个 Date 数据类型,它只包含一个没有时间的日期。因此,您可以执行以下操作:
SELECT CONVERT(date, getdate())
编辑,使用 ISDATE() 对验证、改变方法有意义。
关于该转换错误,我只能假设某些数据不符合某些日期/时间“规则”。考虑到这一点,也许可以尝试这样的事情来发现这些条件。这很简单,但可能会有所帮助。请注意,您可以先将其作为 count(*) 来执行,因为我不知道您正在处理多少条记录,并且不会说这会非常快。
SELECT
yyyymmddxxxxxx
, CASE WHEN isdate( (yyyy + '0101') ) = 0
OR ( yyyy < '1960' OR yyyy > '2020' ) THEN yyyy ELSE '' END AS yyyy
, CASE WHEN isdate( (yyyy + mm + '01') ) = 0 THEN mm ELSE '' END AS mm
, CASE WHEN isdate( (yyyy + mm + dd) ) = 0 THEN dd ELSE '' END AS dd
, CASE WHEN ( hh > '23' ) THEN hh ELSE '' END AS hh
, CASE WHEN ( mi > '59' ) THEN mi ELSE '' END AS mi
, CASE WHEN ( ss > '59' ) THEN ss ELSE '' END AS ss
FROM your_table
CROSS apply (SELECT convert(varchar(14), yyyymmddxxxxxx)) AS ca1 (int2str)
CROSS apply (SELECT
substring(int2str, 1,4) -- yyyy
, substring(int2str, 5,2) -- mm
, substring(int2str, 7,2) -- dd
, substring(int2str, 9,2) -- hh
, substring(int2str,11,2) -- mi
, substring(int2str,13,2) -- ss
) AS ca2 (yyyy,mm,dd,hh,mi,ss)
WHERE ISDATE(convert(varchar(8),int2str,112)) = 0
OR ISDATE( (hh + ':' + mi + ':' + ss) ) = 0
OR ( yyyy < '1960' OR yyyy > '2020' ) -- arbitrary, ignore of change to suit
;
http://sqlfiddle.com/#!3/9ab73/1输出是这样的:
| YYYYMMDDXXXXXX | YYYY | MM | DD | HH | MI | SS |
|----------------|------|----|----|----|----|----|
| 99990410123456 | 9999 | | | | | |
| 20149910123456 | | 99 | 10 | | | |
| 20140499123456 | | | 99 | | | |
| 20140410993456 | | | | 99 | | |
| 20140410129956 | | | | | 99 | |
| 20140410123499 | | | | | | 99 |
| 20140231123499 | | | 31 | | | |