質問

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. 「Julian」文字列を取ります。
  2. 最初の手紙を取り、19日から始まり、世紀に追加します。
  3. 次の2文字から10年と年を加えます。
  4. 最後の3文字である日を最後に追加し、最初のセットアップですでに1日を超えて1を減算します。 (例:2011-01-01)
  5. 結果EX:111186=> 2011-07-05 00:00:00.000
  6. 私の意見では、これは少し不器用で過剰なものです、そして私はこれをするより良い方法があることを願っています。おそらく私はあまりにも多くの変換をしていますか、それとも多分私は異なる方法を使うべきですか?

    関数を改善する方法は?
    おそらく別の、より良い、方法?
    それがもっと読むことができるならば気にしないでください...

    インライン版も持っています。たとえば、読み取り特権を持っていて、乱雑さを使う機能を使用できない場合は、読みやすくすることができますが、それをより読みやすくすることは可能ですか?

    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)
    
    .

役に立ちましたか?

解決

私は、様々な文字列、日付、数値形式のこの切り替えよりも、この切り替えよりも、ネイティブ日時数学を使用することがより効率的です。

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
.

列を索引付けしなくても、それはあなたからの醜い計算を隠しています。列は参照されます...

他のヒント

受け入れられた答えは正しくありません。2016年2月29日になるはずの116060に正しい答えを与えることができません。代わりに2016年3月1日に戻ります。

JDEは整数として日付を記憶するように見えます。

DATEADD(DAY, @Julian % 1000, DATEADD(YEAR, @Julian / 1000, '31-dec-1899'))
.

varchar(6)から行く(6)使用:

DATEADD(DAY, CAST(RIGHT(@Julian,3) AS int), DATEADD(YEAR, CAST(LEFT(@Julian,LEN(@Julian)-3) AS int), '31-dec-1899'))
.

日付(CHAR(1900000 + gldgj))ここで、GLDGJがJulian Date値

USE [master]
GO
/****** Object:  UserDefinedFunction [dbo].[ToGregorian]    Script Date: 08/18/2015 14:33:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[ToGregorian](@julian varchar(6),@time varchar(6))
RETURNS datetime 
AS 
BEGIN
    DECLARE @datetime datetime,@hour int, @minute int, @second int

    set @time = ltrim(rtrim(@time));
    set @julian = ltrim(rtrim(@julian));

    if(LEN(@julian) = 5)
        set @julian = '0' + @julian


    IF(LEN(@time) = 6)
        BEGIN
            SET @hour = Convert(int,LEFT(@time,2));
            SET @minute = CONVERT(int,Substring(@time,3,2));
            SET @second = CONVERT(int,Substring(@time,5,2));
        END
    else IF(LEN(@time) = 5)
        BEGIN
            SET @hour = Convert(int,LEFT(@time,1));
            SET @minute = CONVERT(int,Substring(@time,2,2));
            SET @second = CONVERT(int,Substring(@time,4,2));
        END
    else IF(LEN(@time) = 4)
        BEGIN
            SET @hour = 0;
            SET @minute = CONVERT(int,LEFT(@time,2));
            SET @second = CONVERT(int,Substring(@time,3,2));
        END
    else IF(LEN(@time) = 3)
        BEGIN
            SET @hour = 0;
            SET @minute = CONVERT(int,LEFT(@time,1));
            SET @second = CONVERT(int,Substring(@time,2,2));
        END
    else
        BEGIN
            SET @hour = 0;
            SET @minute = 0;
            SET @second = @time;
        END

    SET @datetime = DATEADD(YEAR,100*CONVERT(INT, LEFT(@julian,1))+10*CONVERT(INT, SUBSTRING(@julian, 2,1))+CONVERT(INT, SUBSTRING(@julian,3,1)),0);                     
    SET @datetime = DATEADD(DAY, CONVERT(INT,SUBSTRING(@julian, 4, 3))-1,@datetime);                   
    SET @datetime = DATEADD(hour,@hour,@datetime)
    SET @datetime = DATEADD(minute,@minute,@datetime);
    SET @datetime = DATEADD(second,@second,@datetime);

    RETURN @datetime
END
.

誰もがそれを述べたとは思わないが、JDEはこれのためだけにテーブルを持っています。

F00365データテーブルです。私が知っている限りでは、それはこの問題のためだけに翻訳表です。

グレゴリア語日付を取得するには、ondtejフィールド(Julian日付)を使用してF00365テーブルに参加し、GregorianであるonDate値を返します。 e.g.

SELECT 
    DateReq.ONDATE 
FROM F00101 NamesData 
INNER JOIN F00365 DateReq 
    ON DateReq.ONDTEJ = NamesData.ABUPMJ
.

数学は必要ありません。うるう年の奇妙な問題はありません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top