SQL поиск даты между значениями или Мин / Макс, если NULL - PullRequest
8 голосов
/ 20 сентября 2010

У меня есть хранимая процедура T-SQL, в которой я хочу найти определенное значение и при желании ограничить поиск определенными датами, если они были переданы. Если для любой из этих дат передаются нулевые значения, то я хочуигнорируй это.То, как я думаю сделать это, устанавливая даты ввода на минимум или максимум, если они равны нулю.Я бы предпочел не жестко задавать минимальные и максимальные значения.Так что мне интересно, каковы SQL-эквиваленты C # DateTime.MaxValue и DateTime.MinValue.

Я думаю об использовании Coalesce, вот такконстанту / переменную / перечисление я могу использовать для переменных <MinDateTime> и <MaxDateTime>?

Есть предложения?

Ответы [ 3 ]

11 голосов
/ 20 сентября 2010

Нет такой функциональности в SQL Server. Вы можете легко найти допустимые значения min и max в BOL (1753-01-01 - 9999-12-31). Или вы можете легко написать другую дату (если вы действительно работаете с днями рождения, 1800-01-01 - 2100-12-31, вероятно, будет достаточно). Или вы могли бы (если это запрос диапазона, который вы показали), чтобы объединение вернулось к самому дню рождения:

SELECT EmployeeName FROM Employee
WHERE  EmployeeID = @EmployeeId AND
Birthday BETWEEN Coalesce(@StartDate, Birthday) AND  
                 Coalesce(@EndDate, Birthday)

Но учтите, что это не обязательно будет хорошо масштабироваться для очень больших таблиц.

Отредактировано после принятия, чтобы ответить на комментарий от OP

Как правило, для SQL, если вам часто требуются "справочные" данные, вы сами добавляете их в виде таблицы. (Google для "таблицы календаря" или "таблицы чисел sql"). Таким образом, в этом случае, если вы хотите, вы можете добавить таблицу «константы» (или, возможно, «пределы»):

create table Constants (
    Lock char(1) not null,
    datetimeMin datetime not null,
    datetimeMax datetime not null,
    intMin int not null,
    intMax int not null,
    /* Other Min/Max columns, as required */
    constraint PK_Constants PRIMARY KEY (Lock),
    constraint CK_Constants_Locked CHECK (Lock='X')
)
insert into Constants (Lock,datetimeMin,datetimeMax,intMin,intMax)
select 'X','17530101','99991231',-2147483648,2147483647

Который вы могли бы затем ссылаться в запросах (либо через подвыбор, либо путем перекрестного соединения с этой таблицей). Э.Г.

SELECT EmployeeName
FROM Employee, Constants
WHERE  EmployeeID = @EmployeeId AND
Birthday BETWEEN Coalesce(@StartDate, Constants.datetimeMin) AND  
                 Coalesce(@EndDate, Constants.datetimeMax)

(ограничения Lock, Primary Key и Check работают вместе, чтобы гарантировать, что в этой таблице когда-либо будет только одна строка)

4 голосов
/ 20 сентября 2010

Для SQL Server, в частности, согласно BOL, ограничения:

  • datetime: 1753-01-01 с 00:00:00 до 9999-12-31 23: 59: 59,997
  • smalldatetime: 1900-01-01 с 00:00:00 до 2079-06-06 23: 59: 29,998
  • date: от 0001-01-01 до 9999-12-31
  • datetime2: 0001-01-01 с 00:00:00 до 9999-12-31 23: 59: 59.9999999

Как видите, это зависит от вашего точного типа данных.

Что касается запроса, я бы сделал это так:

SELECT EmployeeName
FROM Employee
WHERE  EmployeeID = @EmployeeId
 AND  (@StartDate IS NULL
  OR   Birthday >= @StartDate)
 AND  (@EndDate   IS NULL
  OR   Birthday <= @EndDate)
3 голосов
/ 20 сентября 2010

Нет встроенных функций для получения минимального или максимального значения даты и времени.Вы должны жестко закодировать значения или извлечь их из базы данных.

Если параметры NULL, вы можете просто выбрать минимальную и максимальную даты из таблицы Employee.

IF (@StartDate IS Null)
BEGIN
 SELECT @StartDate = MIN(Birthday) FROM Employee
END


IF (@EndDate IS Null)
BEGIN
 SELECT @EndDate = MAX(Birthday) FROM Employee
END

SELECT EmployeeName FROM Employee
WHERE  EmployeeID = @EmployeeId AND
Birthday BETWEEN @StartDate AND  @EndDate
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...