我的表格如下所示
tbPatientEpisode
EpisodeIDP int
EpisodeNumber varcher
EpisodeDate datetime
尝试使用以下SQL查询时
SELECT * FROM tbPatientEpisode
它显示了如下图像的结果..
我想要特定日期的数据,如2013-01-22,我试过以下SQL查询
SELECT * FROM tbPatientEpisode where EpisodeDate like '%2013-01-22%'
但它不会返回任何行。我的查询有什么问题,或者是否有任何正确的方法来获得这种结果......任何帮助都会受到欢迎。
答案 0 :(得分:2)
不要在日期列上使用,它不会起作用。
相反(SQL Server 2008以后):
SELECT *
FROM tbPatientEpisode
where CAST(EpisodeDate as Date) = '2013-01-22'
注意:此表单不会使用以列EpisodeDate
如果要确保使用任何适用的索引(并且适用于SQL Server 2005):
SELECT *
FROM tbPatientEpisode
where EpisodeDate between = '2013-01-22 00:00:00' AND '2013-01-22 23:59:59.997'
答案 1 :(得分:2)
那是因为您的列EpisodeDate
是日期时间类型。
您可以将EpisodeDate
强制转换为日期时间,但它会阻止在列上使用索引,因此我知道最好的方法是将EpisodeDate
与两个日期时间进行比较:
SELECT *
FROM tbPatientEpisode
where
EpisodeDate >= convert(datetime, '20130122', 112) and
EpisodeDate < dateadd(day, 1, convert(datetime, '20130122', 112))
我会解释一下:
首先,您可以将EpisodeDate与字符串进行比较而不进行转换,并依赖于隐式SQL Server转换,但您应该注意两件事:
varchar
比datetime
具有更低的优先级,但是例如,当您的列为varchar
并且您想要将其与{{{{}}进行比较时,它可能会阻止使用索引1}}。所以你可以使用
datetime
但你必须确定你知道自己在做什么
我没有指定select *
FROM tbPatientEpisode
where
EpisodeDate >= '20130122' and
EpisodeDate < '20130123'
而不指定dateadd(day, 1, '20130122')
,因为我正在考虑将20130122作为输入参数,因此您可以在我的查询中替换此字符串
答案 2 :(得分:1)
基于执行计划,通过使用LIKE,系统会将所有列类型转换为VARCHAR,然后只执行扫描
为什么查询中没有结果返回?这是因为系统已经日期时间转换为 nvarchar ,这类似于 2013年1月22日上午10:55
这就是为什么没有结果返回
尝试将您的查询更改为
SELECT * FROM tbPatientEpisode where EpisodeDate like '%Jan 22 2013%'
这应该可以正常工作,以下是使用LIKE的另一种方式,将你的episodeDate投射到某种格式,如'2013-01-22'
SELECT * FROM tbPatientEpisode where CONVERT(NVARCHAR(25),EpisodeDate,126)
like '%2013-01-22%'
最后我希望我的解释能够帮助你理解究竟发生了什么,欢呼兄弟=)
答案 3 :(得分:0)
这个答案首先尝试解释为什么EpisodeDate like '%2013-01-22%'
解决方案不起作用,你可以做些什么来使用like ...
获得所需的结果(我不推荐),最后,我提出了两个解决方案(有和没有隐式转换)。所有查询都可以在AdventureWorks2008R2 sample database上执行:
/*
CREATE INDEX IX_SalesOrderHeader_OrderDate
ON Sales.SalesOrderHeader(OrderDate)
*/
-- It CONVERTs datetime values to VARCHAR with style 0 {Style 0 = mon dd yyyy hh:miAM (or PM)}
-- http://technet.microsoft.com/en-us/library/ms187928.aspx
SELECT TOP(1500)
h.OrderDate,h.SalesOrderID,
CONVERT(VARCHAR(40),h.OrderDate,0) AS OrderDateAsVarChar40, -- Explicit conversion from DATETIME to VARCHAR(40) with style 0
LEFT(h.OrderDate,40) AS ForcingImplicitConvertOnDateTimeColumn -- Implicit conversion because the first argument of LEFT function must be a %CHAR
FROM Sales.SalesOrderHeader h;
/*
OrderDate SalesOrderID OrderDateAsVarChar40 ForcingImplicitConvertOnDateTimeColumn
----------------------- ------------ -------------------- --------------------------------------
2005-07-01 00:00:00.000 43659 Jul 1 2005 12:00AM Jul 1 2005 12:00AM
...
2005-11-19 00:00:00.000 44685 Nov 19 2005 12:00AM Nov 19 2005 12:00AM
2005-11-20 00:00:00.000 44686 Nov 20 2005 12:00AM Nov 20 2005 12:00AM
...
2008-07-31 00:00:00.000 75123 Jul 31 2008 12:00AM Jul 31 2008 12:00AM
*/
-- Result: No rows
SELECT h.OrderDate,h.SalesOrderID
FROM Sales.SalesOrderHeader h
-- The syntax of LIKE operator shows that h.OrderDate must be %CHAR
-- so, SQL Server add an implicit conversion of OrderDate values from DATETIME to VARCHAR
-- http://technet.microsoft.com/en-us/library/ms179859.aspx
WHERE h.OrderDate LIKE '%2005-11-20%'
执行计划:
-- Result: 5 rows
-- I get 5 rows but it's the execution plan is unoptimized (because of Index Scan; see first execution plan)
SELECT h.OrderDate,h.SalesOrderID
FROM Sales.SalesOrderHeader h
WHERE h.OrderDate LIKE 'Nov 20 2005%';
-- Result: 5 rows
-- I get 5 rows and the execution plan includes
-- (1) Index Seek operator instead of Index Scan
-- (2) and implicit conversion of @1 and @2 parameters from varchar to datetime
SELECT h.OrderDate,h.SalesOrderID
FROM Sales.SalesOrderHeader h
WHERE h.OrderDate >= '20051120' AND h.OrderDate < '20051121';
执行计划:
-- Result: 5 rows
-- I get 5 rows and the execution plan includes
-- (1) Index Seek operator instead of Index Scan
-- (2) and no implicit conversion of @1 and @2 parameters
-- See Date, Time, and Timestamp Literals: http://msdn.microsoft.com/en-us/library/windows/desktop/ms710282(v=vs.85).aspx
SELECT h.OrderDate,h.SalesOrderID
FROM Sales.SalesOrderHeader h
WHERE h.OrderDate >= {d '2005-11-20'} AND h.OrderDate < {d '2005-11-21'};
执行计划: