我的问题是我的表将日期存储为
2009-01-10 10:00:00.000
我有另一个表格,将日期存储为
2009-01-10 12:00:00.000
我知道它们不一样,但日期是,在SQL中是否可以轻松地缩短时间并保留比较日期?感谢。
答案 0 :(得分:24)
运行此
SELECT DATEADD(dd, DATEDIFF(d, 0, Getdate()), 0)
将Getdate()更改为列名以删除日期
顺便说一下,如果你进行比较,最好做> =和<因为它会表现更好
答案 1 :(得分:7)
您可以使用以下语法: -
CAST(date_field AS DATE) as column_name
答案 2 :(得分:6)
看here
你想要第一个。
SELECT (CAST(FLOOR(CAST(GETDATE() as FLOAT)) AS DateTime))
不要对varchar使用任何转换,它们很慢。
编辑:@feihtthief - 这是一种从临时数字表(FAST)填充日期表(0时间)的方法。如果需要,编辑它以保存数字表。它们也很方便。
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
答案 3 :(得分:4)
如果您正在使用MS SQL Server 2008,您也可以更改为新的DATE数据类型,而不是使用DATETIME。
答案 4 :(得分:3)
这是一种方式:
declare @d datetime
set @d = getdate()
select dateadd(d, datediff(day, 0, @d), 0)
答案 5 :(得分:2)
转换为varchar是SLOW。不要这样做。 Datediff解决方案速度最快,如果您与日期进行比较,您甚至不必使用dateadd(或者转换为datetime),因为整数将隐含地与没有问题的日期进行比较,如:
WHERE SomeDate = DateDiff(d, 0, GetDate())
Mark Brittingham关于两张牌桌之间联合的建议非常好。并按照建议比较一个日期,使用:
WHERE A.Dt >= @SomeDate AND A.Dt < @SomeDate + 1
答案 6 :(得分:1)
所有这些解决方案(SQL Server 2008数据类型发布除外)都是基于行的解决方案。它们在小桌面情况下可以正常工作,但是它们会在非常大的表格中流失。如果您不在2008年,您是否可以选择将日期存储为年,月,日的单独整数字段,还是作为某个固定日期的计算?
答案 7 :(得分:1)
在Oracle中,你可以做一个截断(DateTime)的东西,摆脱时间组件。 (有像trunc(DateTime,'MONTH')这样的变体,它给出了月份的第一个日期。)不确定这是否是标准SQL,但我确信在其他数据库中会有类似的功能。
这应该比使用转换功能更快。
答案 8 :(得分:1)
像这样的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);
}
};
答案 9 :(得分:0)
我的建议是决定一个标准并更改其中一个表以匹配另一个。否则,您的应用程序代码将不得不记住哪个表永远使用哪种方法。决定标准并坚持下去。如果它真的总是在一张桌子的午夜而且总是在另一张桌子中午,那么日期的时间部分无论如何都没有意义。
答案 10 :(得分:0)
如果您只想找到一种方法来比较日期而不考虑时间组件,那么有很多很好的建议可以将时间用于但是:
Select * From SomeTable Where (DateDiff(d, FirstDate, SecondDate) = 0)
也就是说,使用带有“d”参数的DateDiff进行比较而不是“=”。
以防万一真正
之后答案 11 :(得分:0)
我最喜欢在日期显示(和比较)的方法是使用:
convert(char(10),getdate(),101)
其中getdate()可以是您的日期时间值。
我相信它会转换为MM / DD / YYYY
的格式答案 12 :(得分:0)
在我看来,SQLMenaces建议是从日期中删除时间的最快方法。然而,它也通过删除使用索引的能力使得一些查询像猪一样突然...
[A] JOIN [B] ON SQLMenace([A].datetime) = SQLMenace([B].datetime)
(Where SQLMenace() is the operation he described *grin*)
要在第二个表上使用INDEXes,只需要一个小的适应......
[A] JOIN [B] ON [A].datetime >= SQLMenace([B].datetime) AND [A].datetime < SQLMenace([B].datetime)
这应该导致[B]上的扫描和[A] ...
上的索引查找答案 13 :(得分:0)
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
答案 14 :(得分:0)
根据您将时间归零的原因......
对我来说,通常情况下我可以 比较两个日期 。在这种情况下,如果可以的话,你最好坚持使用&gt; =,&lt; =比较(避免=,&lt;&gt;)。通过这种方式,您可以在WHERE子句中进行比较,而不会失去索引的好处。
如果你在SQl-Server 2008上,他们现在有一个DATE数据类型(不包括时间)
您可以使用一些创意存储格式 - 例如,小型(小型时间的一半)YYDDD,其中DDD是朱利安日期(一年中的每一天按顺序从1到365编号)。这是一个较小的数据类型,对&gt;,=,&lt;有效比较。在进行比较之前,缺点是必须将外部日期转换为此格式(反之亦然)。
我想最后要考虑的是防止时间数据首先存储。
您还可以执行YEAR()
,MONTY()
等,这将返回整数值。可能不是最好的比较日期,但对格式化等很有用。
答案 15 :(得分:-1)
我知道它们不一样,但日期是,在SQL中是否可以轻松地缩短时间并保留比较日期?感谢
好吧,如果该字段的数据类型为 smalldatetime 而不是 datetime ,则您只能使用和更新日期,时间将始终为00:无论你插入什么,都会有00:000。
为了避免日期问题,我个人总是使用
CONVERT( smalldatetime, @myDate, 103 )
一直是103(you can see in the Help)它是dd / mm / yyyy并且和我一起工作正常,我使用这种技术因为我使用英国/法国日期格式,服务器在美国,他们改变了这一切:-D
这是当时(6年前)突然出现在我脑海中的唯一想法,我坚持不懈。
但是,您可以考虑,不添加 DateTime 字段,添加 int 并放置自01-01-1970以来的秒数,您将永远不会有日期问题,每次你需要获取日期时,只需减去那些秒的当前日期。
此技术非常适用于跨国家的大型程序以避免出现问题,例如,名为SuperOffice的世界知名CRM应用程序