Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Conversione della data giuliano JDE in gregoriano

Penso che sia più efficiente utilizzare la matematica datetime nativa rispetto a tutto questo passaggio avanti e indietro a vari formati di stringhe, date e numerici.

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

Risultato:

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

Supponendo che questi dati non cambino spesso, potrebbe essere molto più efficiente memorizzare effettivamente la data come colonna calcolata (motivo per cui ho scelto la data di base di 0 invece di una rappresentazione di stringhe, che causerebbe problemi di determinismo che impediscono la persistenza e l'eventuale indicizzazione della colonna).

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;

Risultati:

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

Anche se non indicizzi la colonna, ti nasconde comunque il brutto calcolo, essendo persistente lo paghi solo al momento della scrittura, poiché non ti fa eseguire costose operazioni funzionali in fase di query ogni volta che viene fatto riferimento a quella colonna ...