Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在SQL中将字符串转换为日期时间_Sql_Sql Server - Fatal编程技术网

在SQL中将字符串转换为日期时间

在SQL中将字符串转换为日期时间,sql,sql-server,Sql,Sql Server,我从另一个系统导入数据,datetime存储为以下格式的字符串: 20061105084755ES yyyymmddhhmmss(es/ed)其中es是EST,而ed是EDT 我将不得不查询这张表的最近30天。我正在使用转换查询: select convert( datetime, left(cdts, 4)+'-'+substring(cdts, 5,2)+'-'substring(cdts, 7,2)+' '+substring(cdts, 9,2) +':'+substr

我从另一个系统导入数据,datetime存储为以下格式的字符串:

20061105084755ES
yyyymmddhhmmss(es/ed)
其中
es
是EST,而
ed
是EDT

我将不得不查询这张表的最近30天。我正在使用转换查询:

select convert(
    datetime,
    left(cdts, 4)+'-'+substring(cdts, 5,2)+'-'substring(cdts, 7,2)+' '+substring(cdts, 9,2) +':'+substring(cdts, 11,2)+':'+substring(cdts, 13,2)
as dt
from tb1
where dt < getdate()-30
选择convert(
日期时间,
左(cdts,4)+'-'+子串(cdts,5,2)+'-'子串(cdts,7,2)+'+子串(cdts,9,2)+':'+子串(cdts,11,2)+':'+子串(cdts,13,2)
as dt
来自tb1
其中dt

我正在寻找一个更高效的查询,它将减少所需时间。此表有大约9000万条记录,查询将永远运行。

一个可能的选项是向表中添加一个日期列,并在加载时填充该信息。这样,在您需要查询它之前,转换就完成了


然后,确保您在该字段上有一个索引,实际查询可以利用该索引。

一个可能的选项是在表中添加一个日期列,并在加载时填充该信息。这样,在您需要查询它之前,转换就完成了

convert(datetime,stuff(stuff(stuff(datevalue, 9, 0, ' '), 12, 0, ':'), 15, 0, ':'))
然后,确保在该字段上有一个实际查询可以利用的索引

convert(datetime,stuff(stuff(stuff(datevalue, 9, 0, ' '), 12, 0, ':'), 15, 0, ':'))


如果您正在执行计算,然后需要根据计算结果进行筛选,则运行时的任何计算都不会加快此查询的速度-SQL Server将被迫执行表扫描。主要问题是您选择将日期存储为字符串。出于各种原因,这是一个糟糕的决定。I是否至少索引了字符串列?如果是,则这可能有助于仅获取过去30天的数据:

DECLARE @ThirtyDays CHAR(8);
SET @ThirtyDays = CONVERT(CHAR(8),DATEADD(DAY,DATEDIFF(DAY,0,GETDATE()),0)-30,112);

SELECT ...
WHERE cdts >= @ThirtyDays;
如果您需要返回除过去30天之外的所有历史记录中的所有数据,这也不会有任何帮助,因为除非您仅从索引列中提取数据,否则检索表中大多数数据的最有效方法是使用聚集索引扫描。(如果您正在检索一组狭窄的列,如果您有覆盖索引,它可能会选择索引扫描。)因此,在这些场景中,您的瓶颈不是公式可以解决的问题,而是实际检索大量数据、通过网络传输数据以及在客户机上呈现数据所需的时间

另外,顺便说一句,你不能这样做:

SELECT a + b AS c FROM dbo.somewhere
WHERE c > 10;

c
dbo中不存在。在某个地方,它是在
SELECT
列表中派生的一个表达式。
SELECT
列表被解析到倒数第二位(就在
ORDER BY
之前),因此您不能引用
WHERE
子句中尚不存在的内容。典型的解决方法是重复表达式或使用子查询/CTE。

如果您正在执行计算,然后需要根据计算结果进行筛选,则运行时的计算不会加快此查询的速度-SQL Server将e被迫执行表扫描。主要问题是您选择将日期存储为字符串。出于各种原因,这是一个糟糕的决定。字符串列是否至少已索引?如果是,则这可能有助于仅获取过去30天的数据:

DECLARE @ThirtyDays CHAR(8);
SET @ThirtyDays = CONVERT(CHAR(8),DATEADD(DAY,DATEDIFF(DAY,0,GETDATE()),0)-30,112);

SELECT ...
WHERE cdts >= @ThirtyDays;
如果您需要返回除过去30天之外的所有历史记录中的所有数据,这也不会有任何帮助,因为除非您仅从索引列中提取数据,否则检索表中大多数数据的最有效方法是使用聚集索引扫描。(如果您正在检索一组狭窄的列,如果您有覆盖索引,它可能会选择索引扫描。)因此,在这些场景中,您的瓶颈不是公式可以解决的问题,而是实际检索大量数据、通过网络传输数据以及在客户机上呈现数据所需的时间

另外,顺便说一句,你不能这样做:

SELECT a + b AS c FROM dbo.somewhere
WHERE c > 10;

c
dbo中不存在。在某个地方,它是在
SELECT
列表中派生的一个表达式。
SELECT
列表被解析到倒数第二位(就在
ORDER BY
之前)因此,你不能在<代码>中引用一些东西,在这里,子句还不存在。典型的解决办法是重复表达式或使用子查询/cTE。

你可以考虑删除图片并实际粘贴查询文本。对于我们中的一些人(我变老了吗?)这张图片真的很难读懂。而且,我们一般都喜欢看到整个查询,如果可以的话,执行计划。人们会问自己的第一个问题是,转换是问题还是别的什么?比如没有索引的表之间的连接。你可以考虑删除图片和实际粘贴。对我们中的一些人来说(我是不是老了?)这张图片真的很难读懂。此外,我们通常喜欢看到整个查询,如果有的话,还有执行计划。人们会问自己的第一个问题是,转换是问题还是其他问题,比如表之间的连接,而不使用索引。感谢您的回答。我只有查询的权限ta谢谢你的回复。我只有查询表格的权限。