テーブルに次の2つの列があります
callstarttime callduration
20180101215910 120
20180101215710 220
最初の列のデータ型はvarchar(255)で、2番目の列はintです。
私が欲しいのは、通話が終了した時間を取得するために、callstarttimeに通話時間を追加することです。
したがって、最初にcallstarttime列をdatetimeに変換してから、Dateadd関数を使用する必要があります。
私のスクリプトは次のとおりです:
select convert(datetime, callstarttime) from Mytable
次のようにキャストも使用してみました
select cast(callstarttime as datetime) from Mytable
ただし、次のエラーが発生します
Conversion failed when converting date and/or time from character string.
同様の質問が varchar列をdatetimeに変換する および このvarcharをdatetime形式に変換する方法? についても尋ねられましたが、そこで提供されているソリューションに基づいてスクリプトを調整することはできません。
これがどのように機能するかを教えてください。
CREATE TABLE #t (callstarttime VARCHAR(255), callduration INT);
INSERT #t ( callstarttime, callduration )
SELECT *
FROM (
VALUES('20180101215910', 120),('20180101215710', 220)
) AS x (callstarttime, callduration);
WITH munge AS (
SELECT *,
LEFT(callstarttime, 8) AS d,
STUFF(STUFF(SUBSTRING(callstarttime, 9, LEN(callstarttime)) , 3, 0, ':'), 6, 0, ':') AS t
FROM #t AS t
)
SELECT *,
TRY_CONVERT(DATETIME, d + ' ' + t),
DATEADD(SECOND, munge.callduration, TRY_CONVERT(DATETIME, d + ' ' + t))
FROM munge
ご存知のとおり、SQL Serverでは、文字シーケンスを有効な日時と見なす前に、数字の間に句読点が必要です。 sp_BlitzErikは、これらの文字を注入する1つの方法を示しました。 SQL Server 2012で導入された [〜#〜] format [〜#〜] 関数を使用した別の例を次に示します。
declare @s varchar(255) = '20180101215910';
declare @i bigint = @s; -- implicit type conversion
select
Raw = @i,
WithSeparators = FORMAT(@i, '####-##-##T##:##:##'),
AsDateTime = CONVERT(datetime, FORMAT(@i, '####-##-##T##:##:##')),
Incremented = DATEADD(SECOND, 120, CONVERT(datetime, FORMAT(@i, '####-##-##T##:##:##')));
Raw WithSeparators AsDateTime Incremented
-------------- -------------------- ----------------------- -----------------------
20180101215910 2018-01-01T21:59:10 2018-01-01 21:59:10.000 2018-01-01 22:01:10.000
整数型に変換する必要があります。これは、FORMATが受け入れるものだからです。桁数のため、BIGINTである必要があります。
パフォーマンスに関しては、2つの手法の違いを測定するのは非常に難しいと思います。
T-SQLの読み方にどの程度慣れているかに応じて、これは認知負荷が小さくなる場合があります。
callstarttimeが標準形式であると想定でき、MSDBで権限を持っている場合、agent_datetime関数で探しているものを取得できます。
CREATE TABLE #mytable (callstarttime varchar(255),callduration int)
INSERT INTO #mytable VALUES ('20180101215910',120),('20180101215710',220)
SELECT
msdb.dbo.agent_datetime(SUBSTRING(callstarttime,1,8), SUBSTRING(callstarttime,9,6)) AS [CallStartTime],
DATEADD(SECOND,callduration,msdb.dbo.agent_datetime(SUBSTRING(callstarttime,1,8), SUBSTRING(callstarttime,9,6))) AS [CallEndTime]
FROM #mytable
DROP TABLE #mytable