1

我的表如下所示

tbPatientEpisode
EpisodeIDP    int
EpisodeNumber varcher
EpisodeDate   datetime

尝试使用以下 SQL 查询时

SELECT * FROM tbPatientEpisode

它向我显示了如下图所示的结果..

结果

我想要特定日期的数据,例如 2013-01-22,为此我在 SQL 查询下尝试过

SELECT * FROM tbPatientEpisode where EpisodeDate  like '%2013-01-22%'

但它不返回任何行。我的查询有什么问题,或者是否有任何适当的方法可以获得这种结果..任何帮助将不胜感激。

4

4 回答 4

4

不要在日期列上使用 like,它不会起作用。

而是(SQL Server 2008 及更高版本):

SELECT * 
FROM tbPatientEpisode 
where CAST(EpisodeDate as Date) = '2013-01-22'

注意:此表单不会使用任何以 column 开头的适用索引EpisodeDate

如果您想确保使用任何适用的索引(并且适用于 SQL Server 2005):

SELECT * 
FROM tbPatientEpisode 
where EpisodeDate between = '2013-01-22 00:00:00' AND '2013-01-22 23:59:59.997'
于 2013-08-17T11:31:42.503 回答
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并且您想将其与datetime.
  • 您必须知道 SQL 服务器如何将您的字符串转换为日期。例如,SQL 服务器可以轻松识别格式 YYYYMMDD,但总的来说,我认为显式转换数据是一种很好的做法。

所以你可以使用你的情况

select *
FROM tbPatientEpisode
where
    EpisodeDate >= '20130122' and 
    EpisodeDate < '20130123'

但你必须确定你知道你在做什么

我没有指定dateadd(day, 1, '20130122'),也不'20130123'是因为我正在考虑将 20130122 作为输入参数,因此您可以在我的查询中替换此字符串

于 2013-08-17T11:32:31.967 回答
1

根据执行计划,通过使用 LIKE,系统会将所有列类型转换为 VARCHAR 然后只执行扫描

为什么您的查询中没有结果返回?这是因为系统已经将日期时间转换为nvarchar,类似于Jan 22 2013 10:55AM

这就是为什么没有结果是返回

尝试将您的查询更改为

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%'

最后我希望我的解释能够帮助你理解到底发生了什么,加油兄弟=)

于 2013-08-18T03:26:31.337 回答
0

这个答案首先试图解释为什么EpisodeDate like '%2013-01-22%'解决方案不起作用,你可以做些什么来获得所需的结果like ...(我不推荐),最后,我提出了两个解决方案(有和没有隐式转换)。所有查询都可以在AdventureWorks2008R2 示例数据库上执行:

/*
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'};

执行计划: 在此处输入图像描述

于 2013-08-17T15:25:15.153 回答