2009-05-15 2 views
1

Если мне нужно искать по дате рождения, которая хранится без часов и минут, но дата, которую я должен искать, включает часы и минуты, что является лучшим способ вернуть все строки, где дата совпавшие только на день, месяц и годБаза данных агностик SQL для возвращаемого списка для даты рождения, хранящейся как временная метка

т.е.
Сохранена 01-JAN-50 10.22.06.000000000
дата выбрана 01-JAN-50 10.22.06.010101120

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

SQL должен работать на Oracle, SQLServer, MySQL и DB2.

+0

Как быстро уроки Y2K забываются! –

+1

Кроме того, комментарий «хранится без часов и минут» не соответствует данным «хранимых как». –

ответ

2

Oracle, типа DATE предварительных даты стандарта SQL версия (как это делает Informix-х), что делает это очень трудно - делать - если не невозможно в нейтральной СУБД. Конечно, возникает вопрос: «Почему выбранное представление данных включает время».

В стандартном SQL очевидной методикой является передача TIMESTAMP в DATE. У нас также нет четкого объяснения данных, которые вы должны искать.

SELECT CAST(DateOfBirth AS DATE), ...other columns... 
    FROM TheMysteryTable   -- Why do people hate giving tables names? 
    WHERE CAST(DateOfBirth AS DATE) = 
      CAST(TIMESTAMP '1950-01-01 10.22.06.010101120' AS DATE) 

Но это предполагает, что вы пишете «дату для поиска с» в качестве литерала. Если это переменная хоста, то тип переменной хоста должен быть DATE, а не TIMESTAMP. Столбец DateOfBirth должен быть DATE, а не TIMESTAMP. Вы не должны использовать TIMESTAMP, если временная часть не является релевантной - она ​​отнимает хранилище и тратит время вычисления.

Обратите внимание, что из-за отливок маловероятно, что СУБД сможет использовать любые индексы или что-то еще.Если типы были в здравом уме, то запрос будет просто:

SELECT DateOfBirth, ...other columns... 
    FROM TheMysteryTable 
    WHERE DateOfBirth = DATE '1950-01-01' 
0

Нет формата даты ANSI, ни манипуляции с строкой. Любой код будет работать только в определенных СУБД, если не один.

Однако, если вы получаете выбранную дату за пределами вашей РСУБД (скажем, PHP, Java и т. Д.), Я бы предложил дезинфицировать ее перед отправкой в ​​запрос; то вы можете сравнить строку с строкой, которая должна работать практически во всех системах.

+0

Глупости. Для DATE существует стандартный формат ANSI (ISO). Вы правы, что он не реализован одинаково повсюду; это будет чрезвычайно сложно - даже невозможно - сделать в формате без СУБД. Но стандарт SQL * * определяет DATE и соответствующий формат, TIME и TIMESTAMP. –

+0

@ Джонатан, посмотри на это ... не знал! возможно, потому что ни одна СУБД не реализует его: P – Seb

1

Поскольку любое решение потребует манипулирования датами и объектами datetime, тогда не будет системно-агностического решения - каждый из них будет иметь разные функции для этих объектов.

Лучшим решением, отличным от абстракции базы данных, было бы округление объекта datetime, используемого в первую очередь, тогда требуется только общее предложение SQL-сравнения, которое будет функционировать во всех перечисленных БД.

+0

Да, я так много думал, я буду дезинфицировать, прежде чем добавлять и искать, спасибо –

0

Как указывали другие, РСУБД очень расходятся, когда дело доходит до обработки данных. Если они фактически следовали стандарту ANSI-92, то следующий должен работать:

SELECT 
    <column list> 
FROM 
    <table name> 
WHERE 
    CAST(birth_date AS DATE) = CAST(search_date AS DATE) 

Потенциальный не самый эффективный способ сделать это, хотя, так как это исключает использование индексов на сегодняшний день для большинства системы. Следующая мощи работы для полностью ANSI-92 совместимой базы данных:

SELECT 
    <column list> 
FROM 
    <table name> 
WHERE 
    birth_date >= CAST(CAST(search_date AS DATE) AS DATETIME) AND 
    birth_date < CAST(CAST(search_date AS DATE) + 1 AS DATETIME) 
Смежные вопросы