El mejor enfoque para eliminar parte del tiempo de fecha y hora en SQL Server

514

¿Qué método proporciona el mejor rendimiento al eliminar la porción de tiempo de un campo de fecha y hora en SQL Server?

a) select DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)

o

b) select cast(convert(char(11), getdate(), 113) as datetime)

El segundo método envía algunos bytes más de cualquier manera, pero eso podría no ser tan importante como la velocidad de la conversión.

Ambos también parecen ser muy rápidos, pero ¿puede haber una diferencia en la velocidad cuando se trata de cientos de miles o más filas?

Además, ¿es posible que existan métodos aún mejores para deshacerse de la porción de tiempo de una fecha y hora en SQL?

Stephen Perelson
fuente
1
Probé esto en un millón de discos en una de mis tablas de producción y no pude obtener una lectura precisa del rendimiento de ninguna manera. Sin embargo, ambos métodos devolvieron exactamente la misma cantidad de datos.
Stephen Perelson el
99
En 18,000,000 filas esto es lo que he encontrado (SQL Server 2008): El método b es aproximadamente un 24% más lento que el método a. CAST (FLOOR (CAST (getdate () AS FLOAT)) AS DATETIME) es un 3,5% más lento que el método a. El método a parece ser un ganador con respecto al rendimiento. Gracias a todos por las excelentes respuestas.
Stephen Perelson el
46
¡¿Por qué diablos SQL no tiene una función incorporada para hacer esto de todos modos? !!
Gary McGill el
10
El nuevo tipo de datos DATE de SQL 2008 se encargará de esto.
Philip Kelley el
2
posible duplicado de la manera más eficiente en SQL Server para obtener la fecha de fecha y hora?
Richard Szalay

Respuestas:

558

Estrictamente, el método aes el que menos recursos requiere:

a) select DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)

Probó menos CPU intensiva para la misma duración total, un millón de filas por alguien con demasiado tiempo en sus manos: ¿ La forma más eficiente en SQL Server para obtener la fecha de la fecha y la hora?

Vi una prueba similar en otro lugar con resultados similares también.

Prefiero el DATEADD / DATEDIFF porque:

  • varchar está sujeto a problemas de formato de idioma / fecha
    Ejemplo: ¿Por qué mi expresión CASE no es determinista?
  • flotador se basa en el almacenamiento interno
  • se extiende para hacer ejercicio el primer día del mes, mañana, etc. cambiando la base "0"

Editar, oct 2011

Para SQL Server 2008+, puede CAST a dateie CAST(getdate() AS date). O simplemente use el datetipo de datos para no tener tiempo de eliminar.

Edit, ene 2012

Un ejemplo práctico de lo flexible que es esto: es necesario calcular por hora redondeada o cifra de fecha en el servidor SQL

Editar, mayo de 2012

No use esto en las cláusulas WHERE y similares sin pensar: agregar una función o CAST a una columna invalida el uso del índice. Vea el número 2 aquí: http://www.simple-talk.com/sql/t-sql-programming/ten-common-sql-programming-mistakes/

Ahora, esto tiene un ejemplo de versiones posteriores del optimizador de SQL Server que administran CAST hasta la fecha correctamente, pero en general será una mala idea ...

Editar, septiembre de 2018, para datetime2

DECLARE @datetime2value datetime2 = '02180912 11:45' --this is deliberately within datetime2, year 0218
DECLARE @datetime2epoch datetime2 = '19000101'

select DATEADD(dd, DATEDIFF(dd, @datetime2epoch, @datetime2value), @datetime2epoch)
gbn
fuente
3
@David Sopko para la edición de octubre de 2011, entonces el código sería: seleccionar elenco (GETDATE () como fecha)
Choco Smith
1
Para versiones más recientes de SQL, usar date en lugar de datetime evita la necesidad de lidiar con horas. Use la siguiente muestra: declare noTime date = getdate (), withTime datetime = getdate () select @ noTime, @ withTime
ozkary
1
el reparto como fecha es genial si solo necesitas la fecha. Sin embargo, a menudo necesita la fecha actual a la medianoche para poder manipular más la fecha. el DATEtiempo de datos es desagradablemente restrictivo en lo que le permitirá hacer con respecto a cosas como dateadd, dateiff e interactuar con otros tipos de datos de fecha / hora. Para esos casos, el DATEADD()enfoque reina el rey.
Xedni
Esto no funciona para todas las fechas. Había ingresado por error en 0218lugar de 2018como el año y la DATEDIFFparte de su declaración arroja una excepción. The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range datetime valueIntente:select DATEDIFF(dd, 0, convert(datetime2(0), '0218-09-12', 120))
Bernhard Döbler el
1
@ BernhardDöbler en julio de 2009 cuando respondí, "0218" habría sido una fecha válida, por lo que no habría llegado tan lejos. Además, el "0" no se convierte a 19000101 para datetime2. Prueba esta selecciónSELECT DATEDIFF(dd, '19000101', convert(datetime2(0), '0218-09-12', 120))
gbn
69

En SQL Server 2008, puede usar:

CONVERT(DATE, getdate(), 101)
Anto Raja Prakash
fuente
13
El tercer argumento no tiene absolutamente ninguna relación con el resultado cuando se convierte de a datetimea date, por lo que su solución se reduce a solo CONVERT(DATE,getdate()), lo que ya se ha sugerido más de una vez.
Andriy M
Simplemente use CAST(GETDATE() AS DATE)o estrictamente ANSI, CAST(CURRENT_TIMESTAMP AS DATE)que creo que no tiene valor. Quédate con el primero.
Ivanzinho
52

Por supuesto, este es un hilo viejo, pero para completarlo.

Desde SQL 2008 puede usar el tipo de datos DATE para que simplemente pueda hacer:

SELECT CONVERT(DATE,GETDATE())
Arjan Fraaij
fuente
21
SELECT CAST(FLOOR(CAST(getdate() AS FLOAT)) AS DATETIME)

... no es una buena solución, según los comentarios a continuación.

Eliminaría esta respuesta, pero la dejaré aquí como contraejemplo, ya que creo que la explicación de los comentaristas de por qué no es una buena idea sigue siendo útil.

Gary McGill
fuente
Vea la respuesta de GBN, muchos han investigado esto. Los DATETIMEs NO se almacenan como flotantes, por lo que el uso de DATEADD / DATEDIFF evita la necesidad de manipulación matemática de CAST entre los tipos.
MatBailie
Puedo aceptar que es posible que desee evitar una conversión de DATETIME a FLOAT por la razón que describe, pero en ese caso, ¿no es la conversión implícita de cero en la opción de OP (a) también un problema? Hmmm ... supongo que en ese caso no es un FLOTANTE y que el servidor es probablemente lo suficientemente inteligente como para descartar la información de tiempo. De acuerdo, admito :-)
Gary McGill
El 0 es de hecho una conversión implícita de un tipo numérico (INT, supongo) a un DATETIME. Sin embargo, debido a que es una expresión constante, el optimizador puede hacer eso en tiempo de compilación para Procedimientos almacenados y solo necesita hacerlo una vez para ejecutar SQL dinámicamente. En resumen, hay una sobrecarga única para eso, la consulta basada en FLOAT tiene la sobrecarga equitativa para cada fila.
MatBailie
Lanzar para flotar es terriblemente poco preciso. Esta respuesta debe ser eliminada. Nadie debería usar este código.
Usr
3
Sin mencionar que no es seguro emitir para flotar y volver a la fecha y hora: el flotador no tiene suficiente precisión. Por lo tanto, creo que no se puede recomendar en absoluto. Vea esta publicación para más detalles .
ErikE
17

En SQL Server 2008, hay un tipo de fecha FECHA (también un tipo de datos HORA).

CAST(GetDate() as DATE)

o

declare @Dt as DATE = GetDate()
Metáfora
fuente
Esto es lo que usé y funcionó bien. Parece la respuesta más simple. ¿Alguna desventaja sobre el uso en conjunto con CONVERTIR?
joelmdev
1
CAST y CONVERT son equivalentes en función. La diferencia es que CAST es parte del estándar ANSI, mientras que CONVERT es específico para T-SQL. Por lo tanto, use CAST siempre que sea posible.
troy
@troy uso CAST porque puedo guardar 3 letras mecanografiadas y la sintaxis es más clara que CONVERT, la parte ANSI Standard no tiene valor
Ivanzinho
8

Aquí hay otra respuesta, de otra pregunta duplicada:

SELECT CAST(CAST(getutcdate() - 0.50000004 AS int) AS datetime) 

Este método de número mágico funciona un poco más rápido que el método DATEADD. (Parece que ~ 10%)

El tiempo de CPU en varias rondas de un millón de registros:

DATEADD   MAGIC FLOAT
500       453
453       360
375       375
406       360

Pero tenga en cuenta que estos números son posiblemente irrelevantes porque ya son MUY rápidos. A menos que tuviera conjuntos de registros de 100,000 o más, ni siquiera podría obtener el tiempo de CPU para leer por encima de cero.

Teniendo en cuenta el hecho de que DateAdd está destinado a este propósito y es más robusto, yo diría que use DateAdd.

Jeff Meatball Yang
fuente
1
Eso es horrible Nunca pondría mis datos en riesgo de esta manera. Quién sabe si esto es correcto para todas las fechas, no solo las que probó.
Usr
@ usr Oh, es correcto, es solo un número mágico y no debe usarse por esa razón. Si desea verificar su corrección, simplemente guarde todas las fechas posibles para un día en una tabla y verifique los resultados. También vea esta publicación para más información.
ErikE
@ErikE buen punto. Sin '12:00:00.003'embargo, su respuesta ofrece la posibilidad de usar lo que creo que es mucho mejor.
Usr
6
SELECT CAST(CAST(GETDATE() AS DATE) AS DATETIME)
Byju
fuente
44
Una opción válida, sí. Sin embargo, sugerido más de una vez en este hilo.
Andriy M
Honestamente, esta solución es la más fácil de leer. My goto
BelgoCanadian
5

De verdad me gusta:

[date] = CONVERT(VARCHAR(10), GETDATE(), 120)

El 120código de formato forzará la fecha en el estándar ISO 8601:

'YYYY-MM-DD' or '2017-01-09'

¡Súper fácil de usar en dplyr ( R) y pandas ( Python)!

emehex
fuente
3

¡TENER CUIDADO!

¡El método a) yb) NO siempre tiene la misma salida!

select DATEADD(dd, DATEDIFF(dd, 0, '2013-12-31 23:59:59.999'), 0)

Salida: 2014-01-01 00:00:00.000

select cast(convert(char(11), '2013-12-31 23:59:59.999', 113) as datetime)

Salida: 2013-12-31 00:00:00.000

(Probado en MS SQL Server 2005 y 2008 R2)

EDITAR: Según el comentario de Adam, esto no puede suceder si lee el valor de la fecha de la tabla, pero puede suceder si proporciona su valor de la fecha como un literal (ejemplo: como un parámetro de un procedimiento almacenado llamado a través de ADO.NET).

broslav
fuente
1
.999 no se puede almacenar en SQL Server en una DATETIMEcolumna. El más alto disponible es .997 De: msdn.microsoft.com/en-us/library/ms187819.aspx verá que los valores se redondean para tener el lugar número mil a 0, 3 o 7. El OP no verá El valor de su prueba en sus tablas.
Adam Wenger
Estás en lo correcto. No quise publicar esto como una respuesta a la pregunta de OP, sino como un comentario para que otros lo vieran, pero solo tenía 11 puntos de reputación y 15 son necesarios para comentar.
broslav
En su primer fragmento, la constante de cadena se convierte implícitamente en una fecha y hora, en su segundo sigue siendo una cadena (y el 113 simplemente se ignora).
Andriy M
2

Franja de tiempo en inserciones / actualizaciones en primer lugar. En cuanto a la conversión sobre la marcha, nada puede vencer a una función definida por el usuario en cuanto al mantenimiento:

select date_only(dd)

La implementación de date_onlypuede ser lo que quieras: ahora se abstrae y el código de llamada es mucho más limpio.

Anton Gogolev
fuente
Una vez ideé un disparador para eliminar los tiempos de las columnas seleccionadas. Si los datos no pueden ser malos, no tiene que limpiarlos.
Philip Kelley el
2
Hay un inconveniente en el enfoque UDF, no son SARGable. Si se usa en cláusulas JOIN o WHERE, el optimizador no puede usar INDEX para mejorar el rendimiento. Sin embargo, usar el enfoque DATEADD / DATEDIFF es SARGable y podrá beneficiarse de los ÍNDICES. (Aparentemente, el método FLOAT también es SARGable)
MatBailie
1
@MatBailie ruego diferir! ¡Los UDF definitivamente no son SARGable, pero tampoco Dateadd ni Convert to float! WHERE DateAdd(DateDiff(Column)) = @DateValueNo usará un índice. Por otro lado, WHERE Column >= dbo.UDF(@DateValue) AND Column < dbo.UDF(@DateValue + 1) es SARGable. Así que ten cuidado de cómo lo pones.
ErikE
2

Vea esta pregunta:
¿Cómo puedo truncar una fecha y hora en SQL Server?

Hagas lo que hagas, no uses el método de cadena . Esa es la peor forma en que puedes hacerlo.

Joel Coehoorn
fuente
Gracias, pensé que esto tenía que haber sido preguntado antes. Sin embargo, es extraño que mis experimentos señalaran que el método float es en realidad más lento en un 3.5% en SQL Server 2008 que el método dateadd (dd, 0, dateiff (dd, 0, getDate ())). Realicé mis pruebas muchas veces para cada método y el servidor de la base de datos no se usó para nada más en ese momento.
Stephen Perelson el
Digamos que soy escéptico con respecto a los puntos de referencia realizados por cualquier persona que no haya demostrado que lo hacen regularmente y de una manera muy científica como parte de su trabajo. Incluso el punto de referencia de Thomas en el enlace de gbn tiene algunos problemas obvios cuando lo miras. Eso no lo hace necesariamente incorrecto, simplemente no definitivo. El método de fundición / piso / fundición fue la forma más rápida aceptada durante mucho tiempo, y sospecho que alguna vez fue indiscutiblemente cierto. Dicho esto, estoy empezando a reconsiderarlo; especialmente para sql server 2008, donde es completamente innecesario de todos modos.
Joel Coehoorn
1
El método de cadena es extremadamente fácil de usar, leer y recordar. ¡Esos son factores muy importantes que creo que estás subestimando!
Ben
1
@JoelCoehoorn, el estilo de conversión 121 se llama "ODBC Canonical". No varía con la clasificación o el entorno local. El truco de la cuerda también es fácil de generalizar a año, año + mes, día, hora o minuto.
Ben
1
@Ben El truco de cadenas enseña a los desarrolladores a usar conversiones de cadenas. Ellos trabajan , pero la fecha de matemáticas es muy, muy superior, por muchas razones, no menos importante de los cuales es la velocidad - pero aún más, por lo que aprender a trabajar con las fechas confiere-como-números en el desarrollador y sus capacidades mentales a ser fluido con la manipulación de números en el código.
ErikE
2

Ya respondí, pero también tiraré esto por ahí ... supuestamente también se realiza bien, pero funciona al tirar el decimal (que almacena el tiempo) del flotador y devolver solo una parte completa (que es la fecha)

 CAST(
FLOOR( CAST( GETDATE() AS FLOAT ) )
AS DATETIME
)

la segunda vez que encontré esta solución ... tomé este código

Carter Cole
fuente
1
La conversión a flotador no es segura .
ErikE
2
CAST(round(cast(getdate()as real),0,1) AS datetime)

Este método no utiliza la función de cadena. Datees básicamente un tipo de datos real con dígitos antes de decimales que son fracción de un día.

Creo que esto será más rápido que muchos.

Shantanu Singh Chauhan
fuente
1
Lanzar como flotador no es seguro .
ErikE
2

Para mí, el siguiente código siempre es un ganador:

SELECT CONVERT(DATETIME, FLOOR(CONVERT(FLOAT,GETDATE())));
usuario1920017
fuente
1
Esencialmente igual a la sugerencia de @Gary McGill .
Andriy M
1
Lanzar como flotador no es seguro .
ErikE
2

seleccione CONVERTIR (char (10), GetDate (), 126)

Diego
fuente
¿Cuál es la diferencia principal de su sugerencia con el método mencionado en la respuesta de @ broslav o con el método que se determinó como el más lento en este hilo (mismo enlace que en la respuesta aceptada)?
Andriy M
1

Creo que quieres decir cast(floor(cast(getdate()as float))as datetime)

real solo tiene 32 bits y podría perder algo de información

Esto es más rápido cast(cast(getdate()+x-0.5 as int)as datetime)

... aunque solo un 10% más rápido(about 0.49 microseconds CPU vs. 0.58)

Esto fue recomendado y toma el mismo tiempo en mi prueba en este momento: DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)

En SQL 2008, la función CLR de SQL es aproximadamente 5 veces más rápida de lo que sería usar una función de SQL, a 1,35 microsegundos frente a 6,5 ​​microsecciones, lo que indica una sobrecarga de llamadas de función mucho menor para una función CLR de SQL frente a una simple UDF de SQL.

En SQL 2005, la función CLR de SQL es 16 veces más rápida, según mis pruebas, en comparación con esta función lenta:

create function dateonly (  @dt datetime )
returns datetime
as
begin
return cast(floor(cast(@dt as float))as int)
end
Aaron West
fuente
1

¿Qué tal select cast(cast my_datetime_field as date) as datetime)? Esto da como resultado la misma fecha, con la hora establecida en 00:00, pero evita cualquier conversión a texto y también evita cualquier redondeo numérico explícito.

Dr. Drew
fuente
Ellos no son los mismos. Las otras respuestas sugirieron enviarlo a una fecha sin componente de tiempo y dejarlo así. Mi publicación lo establece en una fecha y hora con la medianoche. Existe una gran diferencia; intente exportar a MS Excel y verá que maneja la fecha y hora mucho mejor que la fecha.
Dr. Drew
El primero es exactamente el mismo.
Mikael Eriksson
Ok, sí, lo veo ahora. Estaré encantado de eliminar mi respuesta como duplicado, si es necesario.
Dr. Drew
1

Creo que si sigues estrictamente con TSQLesto, esta es la forma más rápida de truncar el tiempo:

 select convert(datetime,convert(int,convert(float,[Modified])))

Encontré que este método de truncamiento es aproximadamente un 5% más rápido que el DateAdd método. Y esto se puede modificar fácilmente para redondear al día más cercano de esta manera:

select convert(datetime,ROUND(convert(float,[Modified]),0))
Jamie G
fuente
La conversión a flotador no es segura .
ErikE
1

Aquí hice una función para eliminar algunas partes de una fecha y hora para SQL Server. Uso:

  • El primer parámetro es la fecha y hora que se quitará.
  • El segundo param es un char:
    • s: redondea a segundos; elimina milisegundos
    • m: redondea a minutos; elimina segundos y milisegundos
    • h: redondea a horas; elimina minutos, segundos y milisegundos.
    • d: redondea a días; elimina horas, minutos, segundos y milisegundos.
  • Devuelve la nueva fecha y hora

create function dbo.uf_RoundDateTime(@dt as datetime, @part as char) returns datetime as begin if CHARINDEX( @part, 'smhd',0) = 0 return @dt; return cast( Case @part when 's' then convert(varchar(19), @dt, 126) when 'm' then convert(varchar(17), @dt, 126) + '00' when 'h' then convert(varchar(14), @dt, 126) + '00:00' when 'd' then convert(varchar(14), @dt, 112) end as datetime ) end

Max Vargas
fuente
Gracias andriy No sabía que mi recomendación no era tan eficiente. Al menos funciona, pero tienes razón.
Max Vargas
1

En caso de que alguien esté buscando una versión de Sybase ya que varias de las versiones anteriores no funcionaron

CAST(CONVERT(DATE,GETDATE(),103) AS DATETIME)
  • Probado en I SQL v11 ejecutándose en Adaptive Server 15.7
Alan
fuente
Esto se ajusta mejor como una edición en la respuesta aceptada. Con otras 20 respuestas, esto será enterrado y casi imposible de encontrar. También la respuesta aceptada menciona el uso cast: para SQL Server 2008+, puede CAST hasta la fecha. O simplemente use la fecha para no tener tiempo para eliminar.
EWit
Sería mejor publicar esto como respuesta a una pregunta equivalente de Sybase. Si no existe tal pregunta, puede crear una (y responderla usted mismo).
Andriy M
Además, no tiene sentido especificar un tercer parámetro para CONVERTIR cuando se convierte un datetimea date: ninguno de los dos tiene un formato inherente.
Andriy M
0

Si es posible, para cosas especiales como esta, me gusta usar las funciones CLR.

En este caso:

[Microsoft.SqlServer.Server.SqlFunction]
    public static SqlDateTime DateOnly(SqlDateTime input)
    {
        if (!input.IsNull)
        {
            SqlDateTime dt = new SqlDateTime(input.Value.Year, input.Value.Month, input.Value.Day, 0, 0, 0);

            return dt;
        }
        else
            return SqlDateTime.Null;
    }
tjeuten
fuente
0

Yo, personalmente, casi siempre uso funciones definidas por el usuario por el para esto si se trata de SQL Server 2005 (o una versión inferior), sin embargo, debe tenerse en cuenta que existen inconvenientes específicos para usar UDF, especialmente si se aplican a las cláusulas WHERE (ver más abajo y los comentarios sobre esta respuesta para más detalles). Si usa SQL Server 2008 (o superior), consulte a continuación.

De hecho, para la mayoría de las bases de datos que creo, agrego estos UDF justo al comienzo, ya que sé que hay un 99% de posibilidades de que los necesite tarde o temprano.

Creo uno para "solo fecha" y "solo hora" (aunque el "solo fecha" es, con mucho, el más usado de los dos).

Aquí hay algunos enlaces a una variedad de UDF relacionados con la fecha:

Funciones esenciales de fecha, hora y fecha y hora de SQL Server
Obtener función solo de fecha

El último enlace muestra no menos de 3 formas diferentes de obtener la fecha solo como parte de un campo de fecha y hora y menciona algunos pros y contras de cada enfoque.

Si usa un UDF, debe tenerse en cuenta que debe intentar evitar usar el UDF como parte de una cláusula WHERE en una consulta, ya que esto dificultará en gran medida el rendimiento de la consulta. La razón principal de esto es que el uso de un UDF en una cláusula WHERE hace que esa cláusula sea no sargable , lo que significa que SQL Server ya no puede usar un índice con esa cláusula para mejorar la velocidad de ejecución de la consulta. Con referencia a mi propio uso de UDF, usaré con frecuencia la columna de fecha "sin procesar" dentro de la cláusula WHERE, pero aplicaré el UDF a la columna SELECTed. De esta forma, el UDF solo se aplica al conjunto de resultados filtrado y no a todas las filas de la tabla como parte del filtro.

Por supuesto, el mejor enfoque absoluto para esto es usar SQL Server 2008 (o superior) y separar sus fechas y horas , ya que el motor de base de datos de SQL Server proporciona de forma nativa los componentes de fecha y hora individuales, y puede consultarlos de manera eficiente de forma independiente sin la necesidad de un UDF u otro mecanismo para extraer la parte de fecha u hora de un tipo de fecha y hora compuesto.

CraigTP
fuente
Usar un UDF puede ser bueno en algunas situaciones (como cuando se limpian los parámetros). Pero en la mayoría de las situaciones es una solución horrible : ejecutar un UDF una vez para cada fila es una forma de matar el rendimiento de una consulta, ¡sin necesidad de hacerlo!
ErikE
@ErikE: no estoy en desacuerdo, Erik, los UDF son asesinos de rendimiento, por eso digo que si puede usar SQL Server 2008 o superior y usar un tipo de datos incorporado que lo haga por usted, esa será la mejor solución (tanto en términos de lograr lo que se requiere como en términos de rendimiento). Si está atascado con una versión anterior de SQL Server que no admite esto de forma nativa, va a renunciar a algo para cumplir con sus requisitos.
CraigTP
Cierto. Sería bueno que el motor de la base de datos nos diera algo SARGable, pero más fácil de expresar. Mientras tanto, si usted está buscando un valor que es cualquier momento durante un día entero, esto sigue siendo la mejor solución (por lo menos las versiones anteriores de SQL): WHERE DateColumn >= {TimeTruncatingExpression}(@DateValue) AND DateColumn < {TimeTruncatingExpression}(@DateValue + 1). Sentí que tenía que decir algo, ya que usted dijo que "casi siempre uso UDF" no explicaba ninguno de los inconvenientes, ni la forma de hacer una consulta de fecha única SARGable.
ErikE
@ErikE - No te preocupes, Erik. Cuando utilicé UDF, o bien estuve trabajando con pequeños conjuntos de datos donde el rendimiento no es primordial, o es más probable que haya estado filtrando la consulta en el campo de fecha "en bruto" (para garantizar la capacidad de respuesta) pero seleccionando la columna con el UDF aplicado. Como estos suelen ser pequeños conjuntos de datos una vez filtrados, ejecutar el UDF sobre este pequeño número de registros no es un problema de rendimiento. Dicho esto, planteas un muy buen punto y he actualizado mi respuesta para reflejar esto.
CraigTP
-4

Yo usaría:

CAST
(
CAST(YEAR(DATEFIELD) as varchar(4)) + '/' CAST(MM(DATEFIELD) as varchar(2)) + '/' CAST(DD(DATEFIELD) as varchar(2)) as datetime
) 

Por lo tanto, crear efectivamente un nuevo campo desde el campo de fecha que ya tiene

Jabu
fuente
2
¿Por qué harías eso? ¿Crees que extraer bits de un datetimevalor, convertirlos en cadenas, concatenarlos juntos y finalmente convertir el resultado nuevamente datetimees mejor que, por ejemplo, realizar cálculos directos en el original datetime(el método DATEADD/ DATEDIFF)?
Andriy M
Además, ¿qué son MMy DD? No hay tales funciones en SQL Server.
Andriy M