web-dev-qa-db-ja.com

SQL Serverでのカスタム日付/時刻フォーマット

テーブルから列を選択し、ResultSetに2つの列を追加するストアドプロシージャを記述しようとしています。これら2つの追加の列は、日時フィールドであるテーブルのフィールドでの変換の結果です。

日時形式フィールドの形式は「YYYY-MM-DD HH:MM:SS.S」です。

次の形式の2つの追加フィールド:

  1. DDMMM
  2. HHMMT。Tは午前の場合は「A」、午後の場合は「P」です。

例:フィールドのデータが「2008-10-12 13:19:12.0」の場合、抽出されたフィールドには次のものが含まれている必要があります。

  1. 10月12日
  2. 0119P

CONVERT文字列形式を使用してみましたが、取得したい出力に一致する形式はありません。 CONVERTを使用してフィールドデータを抽出し、REPLACEを使用する方法について考えていますが、確信が持てないため、ここでいくつかの助けが必要です。

ストアドプロシージャに精通している誰かがここで私を助けてくれますか?ありがとう!

12
Pascal

Dtがdatetime列の場合、

1の場合:

SUBSTRING(CONVERT(varchar, dt, 13), 1, 2)
    + UPPER(SUBSTRING(CONVERT(varchar, dt, 13), 4, 3))

2の場合:

SUBSTRING(CONVERT(varchar, dt, 100), 13, 2)
    + SUBSTRING(CONVERT(varchar, dt, 100), 16, 3)
6
Cade Roux

DATENAMEを使用し、ロジックをストアドプロシージャではなく関数にラップする

declare @myTime as DateTime

set @myTime = GETDATE()

select @myTime

select DATENAME(day, @myTime) + SUBSTRING(UPPER(DATENAME(month, @myTime)), 0,4)

「14OCT」を返します

日付を扱うときは、可能であれば文字/文字列ベースの操作を使用しないようにしてください。これらは数値(float)であり、パフォーマンスはこれらのデータ型変換の影響を受けます。

私が長年にわたって集めてきたこれらの便利な変換を掘り下げてください...

/* Common date functions */
--//This contains common date functions for MSSQL server

/*Getting Parts of a DateTime*/
    --//gets the date only, 20x faster than using Convert/Cast to varchar
    --//this has been especially useful for JOINS
    SELECT (CAST(FLOOR(CAST(GETDATE() as FLOAT)) AS DateTime))

    --//gets the time only (date portion is '1900-01-01' and is considered the "0 time" of dates in MSSQL, even with the datatype min value of 01/01/1753. 
    SELECT (GETDATE() - (CAST(FLOOR(CAST(GETDATE() as FLOAT)) AS DateTime)))


/*Relative Dates*/
--//These are all functions that will calculate a date relative to the current date and time
    /*Current Day*/
    --//now
    SELECT (GETDATE())

    --//midnight of today
    SELECT (DATEADD(ms,-4,(DATEADD(dd,DATEDIFF(dd,0,GETDATE()) + 1,0))))

    --//Current Hour
    SELECT DATEADD(hh,DATEPART(hh,GETDATE()),CAST(FLOOR(CAST(GETDATE() AS FLOAT)) as DateTime))

    --//Current Half-Hour - if its 9:36, this will show 9:30
    SELECT DATEADD(mi,((DATEDIFF(mi,(CAST(FLOOR(CAST(GETDATE() as FLOAT)) as DateTime)), GETDATE())) / 30) * 30,(CAST(FLOOR(CAST(GETDATE() as FLOAT)) as DateTime)))

    /*Yearly*/
    --//first datetime of the current year
    SELECT (DATEADD(yy,DATEDIFF(yy,0,GETDATE()),0))

    --//last datetime of the current year
    SELECT (DATEADD(ms,-4,(DATEADD(yy,DATEDIFF(yy,0,GETDATE()) + 1,0))))

    /*Monthly*/
    --//first datetime of current month
    SELECT (DATEADD(mm,DATEDIFF(mm,0,GETDATE()),0))

    --//last datetime of the current month
    SELECT (DATEADD(ms,-4,DATEADD(mm,1,DATEADD(mm,DATEDIFF(mm,0,GETDATE()),0))))

    --//first datetime of the previous month
    SELECT (DATEADD(mm,DATEDIFF(mm,0,GETDATE()) -1,0))

    --//last datetime of the previous month
    SELECT (DATEADD(ms, -4,DATEADD(mm,DATEDIFF(mm,0,GETDATE()),0)))

    /*Weekly*/
    --//previous monday at 12AM
    SELECT (DATEADD(wk,DATEDIFF(wk,0,GETDATE()) -1 ,0))

    --//previous friday at 11:59:59 PM
    SELECT (DATEADD(ms,-4,DATEADD(dd,5,DATEADD(wk,DATEDIFF(wk,0,GETDATE()) -1 ,0))))

    /*Quarterly*/
    --//first datetime of current quarter
    SELECT (DATEADD(qq,DATEDIFF(qq,0,GETDATE()),0))

    --//last datetime of current quarter
    SELECT (DATEADD(ms,-4,DATEADD(qq,DATEDIFF(qq,0,GETDATE()) + 1,0)))
25
StingyJack

SQLサーバーで次のコマンドを使用して作成できます。

select FORMAT(getdate(), N'yyyy-MM-ddThh:mm:ss')
8
Mehdi

具体的にはあなたの質問に答えていませんが、アプリケーションのプレゼンテーション層で処理する必要があるものではありません。説明した方法でこれを行うと、データベース側に追加の処理が追加されるだけでなく、アプリケーション側で簡単に計算できる、より豊富な日付を持つものに対して、追加のネットワークトラフィックが追加されます(データベースがアプリケーションとは別のマシンにあると想定)。特に、省略された月名を含む最初の例の場合は、ライブラリを処理するだけでなく、言語に依存しません。とにかく、もしあなたがまだこのルートに行くことに決めたなら、他の人が与える答えはあなたを正しい方向に向けるべきです。

6
Kibbee

日時形式フィールドの形式は、「YYYY-MM-DD HH:MM:SS.S」です。

その声明は誤りです。これが、Enterprise ManagerまたはSQL Serverがshow日付を選択する方法です。内部的には8バイトのバイナリ値です。そのため、Andrewによって投稿された一部の関数は非常にうまく機能します。

キブビーも同様に正当な主張をし、完璧な世界では私は彼に同意します。ただし、クエリ結果を表示コントロールまたはウィジェットに直接バインドしたい場合があり、実際にはフォーマットを行う機会がありません。また、プレゼンテーション層は、データベースよりもビジーなWebサーバー上に存在する場合があります。これらを念頭に置いて、SQLでこれを行う方法を知ることは必ずしも悪いことではありません。

4
Joel Coehoorn

はい、出発はそれに対する解決策ですが、私はこの種の方法は長い旅だと思います!

SQLサーバー:

SELECT CAST(DATEPART(DD,GETDATE()) AS VARCHAR)+'/'
+CAST(DATEPART(MM,GETDATE()) AS VARCHAR)
+'/'+CAST(DATEPART(YYYY,GETDATE()) AS VARCHAR)
+' '+CAST(DATEPART(HH,GETDATE()) AS VARCHAR)
+':'+CAST(DATEPART(MI,GETDATE()) AS VARCHAR)

Oracle:

Select to_char(sysdate,'DD/MM/YYYY HH24:MI') from dual

この方法で独自の関数を記述して、この混乱を取り除くことができます。

http://sql.dzone.com/news/custom-date-formatting-sql-ser

select myshortfun(getdate(),myformat)
GO
1
Davut Gürbüz

私はこの回答を(自分用に)カスタム書式に関連するものとして追加します。

アンダースコアyyyy_MM_ddの場合

REPLACE(SUBSTRING(CONVERT(VARCHAR, @dt, 120), 1, 10),'-','_')
0
Pawel Cioch

ここでDATEPARTが必要になります。 DATEPART呼び出しの結果を連結できます。

月の省略形を取得するには、DATENAMEを使用できる場合があります。それがうまくいかない場合は、DATEPARTでCASEステートメントを使用できます。

DATEPARTは時間フィールドでも機能します。

AM/PMインジケーターを取得する方法はいくつか考えられます。たとえば、DATEPARTで作成された新しい日付を比較したり、1日の合計経過秒数を計算したり、既知のAM/PMしきい値と比較したりできます。

0
Paul Williams

次元モデルに必要なDateKeyyyyymmdd)のようなより具体的なものである場合は、キャスト/変換なしで何かを提案します。

DECLARE @DateKeyToday int = (SELECT 10000 * DATEPART(yy,GETDATE()) + 100 * DATEPART(mm,GETDATE()) + DATEPART(dd,GETDATE()));
PRINT @DateKeyToday
0
Mark

mS SQL Serverでできること:

SET DATEFORMAT ymd

年月日、

0
ch2o