Напишите дату в SQL-сервере - PullRequest
       25

Напишите дату в SQL-сервере

68 голосов
/ 17 сентября 2008

В SQL Server, как мне "установить" DATETIME на секунду / минуту / час / день / год?

Допустим, у меня есть дата 2008-09-17 12: 56: 53.430 , тогда выход настила должен быть:

  • Год: 2008-01-01 00: 00: 00.000
  • Месяц: 2008-09-01 00: 00: 00.000
  • День: 2008-09-17 00: 00: 00.000
  • Часы работы: 2008-09-17 12: 00: 00.000
  • Минута: 2008-09-17 12: 56: 00.000
  • Второе: 2008-09-17 12: 56: 53.000

Ответы [ 9 ]

95 голосов
/ 17 сентября 2008

Ключ должен использовать DATEADD и DATEDIFF вместе с соответствующим перечислением временного интервала SQL.

declare @datetime datetime;
set @datetime = getdate();
select @datetime;
select dateadd(year,datediff(year,0,@datetime),0);
select dateadd(month,datediff(month,0,@datetime),0);
select dateadd(day,datediff(day,0,@datetime),0);
select dateadd(hour,datediff(hour,0,@datetime),0);
select dateadd(minute,datediff(minute,0,@datetime),0);
select dateadd(second,datediff(second,'2000-01-01',@datetime),'2000-01-01');
select dateadd(week,datediff(week,0,@datetime),-1); --Beginning of week is Sunday
select dateadd(week,datediff(week,0,@datetime),0); --Beginning of week is Monday

Обратите внимание, что, когда вы настилаете секунду, вы часто получаете арифметическое переполнение, если используете 0. Поэтому выберите известное значение, которое гарантированно будет меньше, чем дата и время, когда вы пытаетесь получить пол.

28 голосов
/ 17 сентября 2008

В SQL Server для этого есть небольшая хитрость:

SELECT CAST(FLOOR(CAST(CURRENT_TIMESTAMP AS float)) AS DATETIME)

Вы приводите DateTime в число с плавающей точкой, которое представляет Date как целую часть, а Time - как долю прошедшего дня. Отрежьте эту десятичную часть, затем приведите ее обратно к DateTime, и у вас будет полночь в начале этого дня.

Это, вероятно, более эффективно, чем все DATEADD и DATEDIFF. Это, конечно, гораздо проще набрать.

11 голосов
/ 18 апреля 2012

Расширяя решение Convert / Cast, в Microsoft SQL Server 2008 вы можете делать следующее:

cast(cast(getdate() as date) as datetime)

Просто замените getdate() на любой столбец с указанием даты и времени.

В этом преобразовании нет строк.

Это нормально для специальных запросов или обновлений, но для соединений ключей или интенсивно используемой обработки может быть лучше обработать преобразование внутри обработки или переопределить таблицы, чтобы иметь соответствующие ключи и данные.

В 2005 году вы можете использовать нижний этаж: cast(floor(cast(getdate() as float)) as datetime)

Не думаю, что для этого также используется преобразование строк, но я не могу говорить о сравнении фактической эффективности с оценками кресла.

6 голосов
/ 25 июля 2013

Я использовал @ ответ Портмана много раз за эти годы в качестве справочного материала при датировании настила и перевел его работу в функцию, которая может оказаться вам полезной.

Я не претендую на его производительность и просто предоставляю его как инструмент для пользователя.

Я прошу вас, если вы решите поднять этот ответ, пожалуйста, также наберите @ ответ Портмана , так как мой код является его производным.

IF OBJECT_ID('fn_FloorDate') IS NOT NULL DROP FUNCTION fn_FloorDate
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[fn_FloorDate] (
  @Date DATETIME = NULL,
  @DatePart VARCHAR(6) = 'day'
)
RETURNS DATETIME
AS
BEGIN
  IF (@Date IS NULL)
    SET @Date = GETDATE();

  RETURN
  CASE
    WHEN LOWER(@DatePart) = 'year' THEN DATEADD(YEAR, DATEDIFF(YEAR, 0, @Date), 0)
    WHEN LOWER(@DatePart) = 'month' THEN DATEADD(MONTH, DATEDIFF(MONTH, 0, @Date), 0)
    WHEN LOWER(@DatePart) = 'day' THEN DATEADD(DAY, DATEDIFF(DAY, 0, @Date), 0)
    WHEN LOWER(@DatePart) = 'hour' THEN DATEADD(HOUR, DATEDIFF(HOUR, 0, @Date), 0)
    WHEN LOWER(@DatePart) = 'minute' THEN DATEADD(MINUTE, DATEDIFF(MINUTE, 0, @Date), 0)
    WHEN LOWER(@DatePart) = 'second' THEN DATEADD(SECOND, DATEDIFF(SECOND, '2000-01-01', @Date), '2000-01-01')
    ELSE DATEADD(DAY, DATEDIFF(DAY, 0, @Date), 0)
  END;
END

Использование:

DECLARE @date DATETIME;
SET @date = '2008-09-17 12:56:53.430';

SELECT
  @date AS [Now],--2008-09-17 12:56:53.430
  dbo.fn_FloorDate(@date, 'year') AS [Year],--2008-01-01 00:00:00.000
  dbo.fn_FloorDate(default, default) AS [NoParams],--2013-11-05 00:00:00.000
  dbo.fn_FloorDate(@date, default) AS [ShouldBeDay],--2008-09-17 00:00:00.000
  dbo.fn_FloorDate(@date, 'month') AS [Month],--2008-09-01 00:00:00.000
  dbo.fn_FloorDate(@date, 'day') AS [Day],--2008-09-17 00:00:00.000
  dbo.fn_FloorDate(@date, 'hour') AS [Hour],--2008-09-17 12:00:00.000
  dbo.fn_FloorDate(@date, 'minute') AS [Minute],--2008-09-17 12:56:00.000
  dbo.fn_FloorDate(@date, 'second') AS [Second];--2008-09-17 12:56:53.000
2 голосов
/ 17 сентября 2008

Функция CONVERT () также может делать это, в зависимости от используемого стиля.

1 голос
/ 17 сентября 2008

Жаль, что это не Oracle, иначе вы можете использовать trunc () или to_char ().

Но у меня были похожие проблемы с SQL Server, и я использовал методы CONVERT () и DateDiff (), на которые ссылается здесь

0 голосов
/ 05 мая 2016

DateAdd вместе с DateDiff могут помочь в выполнении множества различных задач. Например, вы можете найти последний день любого месяца, а также последний день предыдущего или следующего месяца.

----Last Day of Previous Month
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE()),0))
LastDay_PreviousMonth
----Last Day of Current Month
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0))
LastDay_CurrentMonth
----Last Day of Next Month
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+2,0))
LastDay_NextMonth

Источник

0 голосов
/ 02 октября 2014

Есть несколько способов снять шкуру с этой кошки =)

select convert(datetime,convert(varchar,CURRENT_TIMESTAMP,101))
0 голосов
/ 18 февраля 2009

Поскольку PostgreSQL также является «SQL-сервером», я упомяну

date_trunc()

Что делает именно то, что вы изящно просите.

Например:

 select date_trunc('hour',current_timestamp);
       date_trunc
------------------------
 2009-02-18 07:00:00-08
(1 row)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...