Подтвердить что ты не робот

Поместить дату на SQL-сервере

В 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
4b9b3361

Ответ 1

Ключ должен использовать 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. Поэтому выберите известное значение, которое гарантировано будет ниже, чем время, которое вы пытаетесь выполнить.

Ответ 2

В SQL Server здесь небольшой трюк:

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

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

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

Ответ 3

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

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

Просто замените getdate() на любой столбец, являющийся datetime.

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

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

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

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

Ответ 4

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

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

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

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

Ответ 5

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

Ответ 6

Слишком плохо это не Oracle, иначе вы могли бы использовать trunc() или to_char().

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

Ответ 7

Существует несколько способов скинуть этот cat =)

select convert(datetime,convert(varchar,CURRENT_TIMESTAMP,101))

Ответ 8

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

Источник

Ответ 9

Так как PostgreSQL также является "SQL Server", я упомянул

date_trunc()

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

Например:

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