Ответ 1
Запустите этот
SELECT DATEADD(dd, DATEDIFF(d, 0, Getdate()), 0)
измените Getdate() на ваше имя столбца, чтобы удалить дату
Кстати, если вы делаете сравнение, лучше делать >= и < так как он будет работать лучше
У меня проблема, когда моя таблица хранит дату как
2009-01-10 10:00:00.000
и у меня есть другая таблица, которая хранит дату как
2009-01-10 12:00:00.000
Я знаю, что они не то же самое, но даты, есть ли в SQL, чтобы легко отбросить время и сохранить только даты для сравнения? Спасибо.
Запустите этот
SELECT DATEADD(dd, DATEDIFF(d, 0, Getdate()), 0)
измените Getdate() на ваше имя столбца, чтобы удалить дату
Кстати, если вы делаете сравнение, лучше делать >= и < так как он будет работать лучше
Вы можете использовать этот синтаксис: -
CAST(date_field AS DATE) as column_name
Посмотрите здесь
Вы хотите первый.
SELECT (CAST(FLOOR(CAST(GETDATE() as FLOAT)) AS DateTime))
Не используйте преобразования в varchar, они медленны.
EDIT: @feihtthief. Вот способ заполнения таблицы дат (с 0 раз) из таблицы номеров тем, которая является FAST. Отредактируйте его, чтобы сохранить таблицу чисел, если хотите. Они также удобны.
DECLARE @DaysFromGoLive int
SET @DaysFromGoLive = (SELECT (DATEDIFF(dd,'10/01/2007',GETDATE()) + 1)) /* Days from go live is the starting date of the table */
SELECT TOP 10950 --30 years of days
IDENTITY(INT,1,1) as N
INTO #Numbers
FROM Master.dbo.SysColumns sc1,
Master.dbo.SysColumns sc2
CREATE TABLE [dbo].[TableOfDates](
[fld_date] [datetime] NOT NULL,
CONSTRAINT [PK_TableOfDates] PRIMARY KEY CLUSTERED
(
[fld_date] ASC
)WITH FILLFACTOR = 99 ON [PRIMARY]
) ON [PRIMARY]
INSERT INTO
dbo.TableOfDates
SELECT
DATEADD(dd,nums.n - @DaysFromGoLive,CAST(FLOOR(CAST(GETDATE() as FLOAT)) as DateTime)) as FLD_Date
FROM #Numbers nums
SELECT MIN(FLD_Date) FROM dbo.TableOfDates
SELECT MAX(FLD_Date) FROM dbo.TableOfDates
DROP TABLE #Numbers
Если вы используете MS SQL Server 2008, вы также можете изменить новый тип данных DATE вместо использования DATETIME.
Здесь один из способов:
declare @d datetime
set @d = getdate()
select dateadd(d, datediff(day, 0, @d), 0)
Преобразование в varchar - SLOW. Не делай этого. Решение Datediff является самым быстрым, и если вы сравниваете дату с датой, вам даже не нужно использовать dateadd (или попеременно конвертировать в datetime), поскольку целое число будет неявно сравнивать с датой без проблем, например:
WHERE SomeDate = DateDiff(d, 0, GetDate())
Предложение Марка Бриттингема о соединении между двумя таблицами довольно хорошо. И для сравнения с одной датой, как было предложено, используйте:
WHERE A.Dt >= @SomeDate AND A.Dt < @SomeDate + 1
Все эти решения (за исключением столбца данных SQL Server 2008) представляют собой решения на основе строк. Они будут хорошо работать в ситуациях с небольшими столами, но они будут работать в очень больших настольных корпусах. Если вы не в 2008 году, у вас есть возможность сохранить дату в виде отдельных целых полей для года, месяца и дня или в качестве расчета с определенной фиксированной даты?
В Oracle вы можете сделать trunc (DateTime), который избавится от компонента времени. (Существуют такие вариации, как trunc (DateTime, "MONTH" ), который дает первую дату месяца.) Не уверен, что это стандартный SQL, но я уверен, что в других базах были бы подобные функции.
Это должно быть намного быстрее, чем работать с функцией преобразования.
Функция SQL CLR, как это, должна ему:
public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlDateTime StripTime(SqlDateTime date)
{
return date.IsNull ? SqlDateTime.Null : new SqlDateTime(date.DayTicks, 0);
}
};
Мое предложение - принять решение по стандарту и изменить одну из таблиц в соответствии с другой. В противном случае ваш код приложения должен будет помнить, какая таблица использует этот метод навсегда. Решите по стандарту и придерживайтесь его. Если это действительно всегда полночь в одной таблице и всегда полдень в другой таблице, тогда временная часть даты не имеет никакого значения.
Есть много прекрасных предложений для того, чтобы убрать время, но если вы просто ищете способ сравнить дни, не учитывая компонент времени, просто выполните это:
Select * From SomeTable Where (DateDiff(d, FirstDate, SecondDate) = 0)
То есть, используйте DateDiff с аргументом "d", чтобы выполнить ваше сравнение, а не "=".
На всякий случай это то, что вы действительно после...
Моим любимым способом отображения (и сравнения) даты является использование:
convert(char(10),getdate(),101)
где getdate() может быть вашим значением datetime.
Я считаю, что он преобразуется в формат MM/DD/YYYY
SQLMenaces предлагает, на мой взгляд, самый быстрый способ снять время с даты. Тем не менее, он вызывает некоторые запросы, как свинья, удаляя возможность использовать индексы...
[A] JOIN [B] ON SQLMenace([A].datetime) = SQLMenace([B].datetime)
(Where SQLMenace() is the operation he described *grin*)
Чтобы использовать возможность использования ИНДЕКСОВ во 2-й таблице, ему просто нужна небольшая адаптация...
[A] JOIN [B] ON [A].datetime >= SQLMenace([B].datetime) AND [A].datetime < SQLMenace([B].datetime)
Это должно вызвать сканирование на [B] и индексные запросы на [A]...
StingyJack имеет это право, но в зависимости от того, что вы хотите сделать, вы можете лучше хранить дату в виде целого числа, если вам не нужна временная часть.
create table #datedemo(
id integer primary key identity(1,1) not null
,date datetime not null
,dateint int
)
insert into #datedemo (date)
select '2009-Jan-29 02:12:00'
union all select '2009-Jan-29 16:22:00'
union all select '2009-Jan-30 00:32:00'
union all select '2009-Jan-30 13:42:00'
union all select '2009-Jan-31 01:52:00'
union all select '2009-Feb-01 12:02:00'
update #datedemo set dateint = floor(cast(date as float))
select id,date,dateint,cast(dateint as datetime) from #datedemo
where dateint = floor(cast(cast('2009-Jan-30' as datetime)as float))
drop table #datedemo
В зависимости от вашей причины обнуления времени...
Для меня часто было так, что я мог сравнить две даты. В этом случае вы лучше придерживаетесь > =, <= сравнения (avoid =, < > ), если сможете. Таким образом, вы можете выполнять сравнения в своем предложении WHERE, не теряя при этом преимущества своего индекса.
Если вы находитесь на SQl-сервере 2008, у них теперь есть тип данных DATE (который не включает время)
Вы можете использовать некоторый формат хранения объявлений - например, smallint (половина от размера smalldatetime) YYDDD, где DDD - это юлианская дата (каждый день года пронумерован последовательно от 1 до 365). Это меньший тип данных и действителен для > , =, < сравнения. Недостаток заключается в том, чтобы преобразовать внешние даты в этот формат (или наоборот), прежде чем выполнять сравнение.
Я думаю, что последнее, что нужно учитывать, - это предотвращать хранение данных во времени.
Вы также можете сделать YEAR()
, MONTY()
и т.д., которые возвратят целочисленные значения. Не лучше всего сравнивать даты, но полезно для форматирования и т.д.
Я знаю, что они не то же самое, но даты, есть ли в SQL, чтобы легко отбросить время и сохранить только даты для сравнения? Благодаря
Хорошо, если тип данных поля smalldatetime вместо datetime, вы сможете использовать и обновлять даты, время всегда будет 00: 00: 000 независимо от того, что вы вставляете.
Чтобы избежать проблем с датами, я лично всегда использую
CONVERT( smalldatetime, @myDate, 103 )
был 103 (вы можете видеть в справке) it'a dd/mm/yyyy и отлично работает со мной, я использую этот метод, потому что я использую формат даты в Великобритании и Франции, а серверы находятся в США, где они меняют все: -D
это была единственная идея, которая появилась в моей голове в то время (6 лет назад), и я застрял с ней.
Но вы можете подумать, вместо добавления поля DateTime, добавьте int и поместите количество секунд с 01-01-1970, вы никогда не сможете есть проблемы с датой, и каждый раз, когда вам нужно получить дату, просто вычтите текущую дату в эти секунды.
Этот метод очень часто используется в больших программах для разных стран, чтобы избежать проблем, например, всемирно известное CRM-приложение, называемое SuperOffice