2

私はJDE の日付を変換しようとしていますが、大量の情報を収集して、いくつかのタスクを簡素化するために SQL 変換関数を実行しようと考えました。

これが私が思いついた関数で、単に「ToGregorian」と呼んでいます

CREATE FUNCTION [dbo].[ToGregorian](@julian varchar(6))
RETURNS datetime AS BEGIN
    DECLARE @datetime datetime

    SET @datetime = CAST(19+CAST(SUBSTRING(@julian, 1, 1) as int) as varchar(4))+SUBSTRING(@julian, 2,2)+'-01-01'
    SET @datetime = DATEADD(day, CAST(SUBSTRING(@julian, 4,3) as int)-1, @datetime)

    RETURN @datetime
END
  1. 「ジュリアン」文字列を取ります。
  2. 最初の文字を取り、19 から始まる世紀に追加します。
  3. 次の 2 文字から 10 年と年を追加します。
  4. 最後に、最後の 3 文字である日を追加し、最初のセットアップですでに 1 日あったため、1 を減算します。(例: 2011-01-01)
  5. 結果の例: 111186=>2011-07-05 00:00:00.000

私の意見では、これは少し不器用でやり過ぎです。これを行うためのより良い方法があることを願っています。おそらく私はあまりにも多くの変換を行っていますか、それとも別の方法を一緒に使用する必要がありますか?

機能を改善するためのアドバイスはありますか?
おそらく、別のより良い方法でしょうか?
もっと読みやすくなっても構いません...

インライン バージョンもあります。たとえば、読み取り権限しかなく、関数を使用できない場合、これも乱雑に見えますが、より読みやすく、またはより良くすることは可能ですか?

CAST(REPLACE(Convert(VARCHAR, DATEADD(d,CAST(SUBSTRING(CAST([column] AS VARCHAR), 4,3) AS INT)-1, CAST(CAST(19+CAST(SUBSTRING(CAST([column] AS VARCHAR), 1,1) AS INT) AS VARCHAR)+SUBSTRING(CAST([column] AS VARCHAR), 2,2) + '-01-01' AS DATETIME)), 111), '/', '-') AS DATETIME)
4

5 に答える 5

4

さまざまな文字列、日付、数値形式に切り替えるよりも、ネイティブの日時計算を使用する方が効率的だと思います。

DECLARE @julian VARCHAR(6) = '111186';

SELECT DATEADD(YEAR, 
  100*CONVERT(INT, LEFT(@julian,1))
  +10*CONVERT(INT, SUBSTRING(@julian, 2,1))
  +CONVERT(INT, SUBSTRING(@julian,3,1)), 
 DATEADD(DAY, CONVERT(INT,SUBSTRING(@julian, 4, 3))-1, 
 0));

結果:

===================
2011-07-05 00:00:00

このデータが頻繁に変更されないと仮定すると、実際に日付を計算列として格納する方がはるかに効率的である可能性があります (そのため、0文字列表現の代わりに基準日付を選択しました。永続化され、インデックス化される可能性があります)。

CREATE TABLE dbo.JDEDates
(
    JDEDate VARCHAR(6),

    GregorianDate AS CONVERT(SMALLDATETIME, 
      DATEADD(YEAR, 
        100*CONVERT(INT, LEFT(RIGHT('0'+JDEDate,6),1))
        +10*CONVERT(INT, SUBSTRING(RIGHT('0'+JDEDate,6), 2,1))
        +CONVERT(INT, SUBSTRING(RIGHT('0'+JDEDate,6),3,1)), 
      DATEADD(DAY, CONVERT(INT, RIGHT(JDEDate, 3))-1, 
      0))
    ) PERSISTED
);

INSERT dbo.JDEDates(JDEDate) SELECT '111186';

SELECT JDEDate, GregorianDate FROM dbo.JDEDates;

結果:

JDEDate GregorianDate
======= ===================
111186  2011-07-05 00:00:00

列にインデックスを付けない場合でも、醜い計算は隠されます。その列が参照されるたびに、クエリ時に高価な関数操作を実行する必要がないため、書き込み時にのみ支払う必要があります。 ...

于 2012-03-12T17:29:26.707 に答える
1

DATE(CHAR(1900000 + GLDGJ)) GLDGJ はユリウス日の値です

于 2015-12-15T15:11:16.077 に答える