2013-08-17 5 views
-1

Моя таблица выглядит, как показано нижеSQL запрос на выборку для конкретной даты

tbPatientEpisode 
EpisodeIDP int 
EpisodeNumber varcher 
EpisodeDate datetime 

когда попробуйте ниже SQL запроса

SELECT * FROM tbPatientEpisode 

это мне показать результаты, как ниже изображение ..

Result

Я хочу данные для конкретной даты, например, 2013-01-22 для этого, я попробовал под SQL-запрос

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

, но он не возвращает ни одного ряда. что не так с моим запросом или есть какой-либо правильный способ получить такой результат. Любая помощь будет оценена.

+3

не использовать, как на сегодняшний день колонок. –

ответ

2

это потому, что ваша колонка EpisodeDate является DateTime типа. Вы могли бросить EpisodeDate в дату, но это будет предотвратить использование индексов в столбце, поэтому лучший способ я знаю, чтобы сравнить EpisodeDate с двумя DateTimes:

SELECT * 
FROM tbPatientEpisode 
where 
    EpisodeDate >= convert(datetime, '20130122', 112) and 
    EpisodeDate < dateadd(day, 1, convert(datetime, '20130122', 112)) 

Я объясню немного:

First , вы могли бы сравнить EpisodeDate в строку без преобразования и полагаться на неявное преобразование SQL Server, но вы должны знать две вещи:

  • Priority of types. При сравнении валусов разных типов данные с более низким приоритетом будут преобразованы в тип с более высоким приоритетом. Это хорошо в нашем случае, потому что varchar имеют более низкий приоритет, чем datetime, но это может помешать использовать индексы, когда, например, ваш столбец varchar, и вы хотите сравнить его с datetime.
  • Вы должны знать, как SQL-сервер преобразует вашу строку на сегодняшний день. Например, SQL-сервер может легко распознать формат YYYYMMDD, но в целом я считаю, что хорошей практикой является прямое преобразование данных.

Так что ваш случай вы можете использовать

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

, но вы должны быть уверены, что вы знаете, что вы делаете

Я не указан dateadd(day, 1, '20130122') и не '20130123', потому что я м думать о 20130122 в качестве входных параметров, поэтому вы можете заменить эту строку в моем запросе

+0

Объясните себя downvoters :) –

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' 
+0

'@Mitch Wheat' это показывает мне предупреждение, как' Тип дата не определенный тип системы .'. – Vijay

+1

@win Он упоминает, что запрос работает только на SQL Server 2008 и новее, 'DATE' (afaik) не является типом SQL Server 2005. –

+0

Да, я знаю. PLS перечитывать ответ. –

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

Исполнение: План enter image description here

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

Исполнение: План enter image description here

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

Исполнение: enter image description here

+0

Тип '{d '2005-11-20'}' is 'datetime':' SELECT SQL_VARIANT_PROPERTY ({d '2005-11-20'}, 'BaseType') '. –

1

на основе плана выполнения, используя LIKE, система преобразует весь тип столбца в VARCHAR, а затем выполняет только сканирование

Почему в вашем запросе нет результата возврата? это происходит потому, что система уже конвертирована DateTime в NVARCHAR который является чем-то вроде 22 Jan 2013 10:55 AM

и поэтому существует никакого результата не возвращает

попробуйте изменить запрос

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

наконец я надеюсь, что мое объяснение может помочь у понять, что именно происходит, подбодрить брата =)