Независимый от базы данных SQL для возврата списка даты рождения, хранящегося в виде отметки времени.
-
22-08-2019 - |
Вопрос
Если мне нужно выполнить поиск по дате рождения, которая хранится без часов и минут, но дата, по которой мне нужно искать, включает часы и минуты, каков наилучший способ вернуть все строки, в которых дата сопоставляется только по дню, месяцу и году
то есть
Хранится как 01-ЯНВ-50 22.10.06.000000000
дата выбрана 01.01.50 22.10.06.010101120
Если я использую дату с часами и минутами, SQL вернет только строки с точной отметкой времени, а не строки только для дня, месяца и года.
SQL должен работать на Oracle, SQLServer, MySQL и DB2.
Решение
Тип DATE Oracle предшествует стандартной версии 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'
Другие советы
Поскольку любое решение потребует манипулирования объектами date и datetime, тогда не будет системно-зависимого решения — каждое из них будет иметь разные функции для этих объектов.
Лучшим решением, кроме абстракции базы данных, было бы сначала округлить используемый объект datetime, а затем потребуется только общее предложение сравнения SQL, которое будет работать во всех перечисленных БД.
Нет формата даты ANSI и манипуляций со строками.Любой код будет работать только в определенных СУБД, если не в одной.
Однако, если вы получаете выбранную дату за пределами вашей СУБД (скажем, PHP, Java и т. д.), я бы предложил очистить ее перед отправкой в запросе;затем вы можете сравнить строку со строкой, что должно работать практически во всех системах.
Как отмечали другие, СУРБД очень различаются в том, что касается обработки дат и времени. Если они фактически следовали стандарту 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)
Используйте ИЗВЛЕЧЕНИЕ()