Один SQL-запрос, который может обрабатывать как нулевой, так и оцененный диапазон дат на SQL-сервере. - PullRequest
6 голосов
/ 05 октября 2009

Использование SQL Server 2008. У меня есть сохраненный процесс, в котором исходная и конечная даты указаны в качестве входных параметров для диапазона дат.

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

Я не хочу использовать оператор IF.

Ответы [ 7 ]

12 голосов
/ 05 октября 2009
WITH    limits AS
        (
        SELECT  COALESCE(@startDate, MIN(mydate)) AS startDate, COALESCE(@endDate, MAX(mydate)) AS endDate
        FROM    mytable
        )
SELECT  m.*
FROM    limits
JOIN    mytable m
ON      mydate BETWEEN startDate AND endDate

Это будет наиболее эффективно, если есть индекс на mydate, так как это условие может быть sargable и будет использовать Index Seek.

Если индекса нет, тогда используйте IFNULL конструкции, предложенные другими.

10 голосов
/ 05 октября 2009

Вы можете сделать это:

SELECT blah
FROM MyTable
WHERE 
    (@startDate IS NULL OR MyTable.StartDate >= @startDate)
    AND (@endDate IS NULL OR MyTable.EndDate <= @endDate)

Но учтите, что большое количество параметров в таких предложениях AND может привести к неправильному кешированию планов запросов. На SO много вопросов о неправильных планах запросов и параметре 'sniffing'.

4 голосов
/ 05 октября 2009

Ответ Кассной, вероятно, лучший, но вот еще один вариант:

SELECT *
FROM MyTable
WHERE 
    MyTable.StartDate >= ISNULL(@startDate, MyTable.StartDate)
    AND MyTable.EndDate <= ISNULL(@startDate, MyTable.EndDate)
2 голосов
/ 05 октября 2009
SELECT *
FROM MyTable
WHERE 
     MyTable.StartDate >= COALESCE(MyTable.StartDate, "1/1/1900") 
     /* Date selected as earliest plausible constant to avoid min() lookup */

 AND MyTable.EndDate <= COALESCE(MyTable.EndDate, "1/1/3001")
     /* Date selected as latest plausible constant to avoid max() lookup */

Вам необходимо выбрать правильные константы для вашего приложения / домена, очевидно. Это немного рискованно, если у вас недостаточно широкие константы, но намного быстрее, чем явно выглядящие min / max из таблицы, а большинство приложений / доменов имеют довольно четко определенные кадры.

1 голос
/ 04 октября 2013

Вы можете сделать это

SELECT blah
FROM MyTable
WHERE 
1 = case 
        when @startDate IS NOT NULL then  MyTable.Date >= @startDate
    else 1 end
AND
1 = case 
        when @endDate IS NOT NULL then  MyTable.Date <= @endDate
    else 1 end

или

SELECT blah
FROM MyTable
WHERE 
(
    (@startDate is not null and @endDate is not null and MyTable.Date between @startDate and @endDate )
    or
    (@startDate is null and @endDate is null )
)
1 голос
/ 05 октября 2009
SELECT
    Column1,....
    FROM MyTable
    WHERE MyTable.StartDate>=COALESCE(@startDate,CONVERT(datetime,'01/01/1753'))
        AND MyTable.EndDate<=COALESCE(@endDate,CONVERT(datetime,'12/31/9999'))

также, вот очень полная статья на эту тему:

Условия динамического поиска в T-SQL Эрланда Соммарского

охватывает все проблемы и методы попытки написания запросов с несколькими необязательными условиями поиска.

вот оглавление:

   Introduction
      The Case Study: Searching Orders
      The Northgale Database
   Dynamic SQL
      Introduction
      Using sp_executesql
      Using the CLR
      Using EXEC()
      When Caching Is Not Really What You Want
   Static SQL
      Introduction
      x = @x OR @x IS NULL
      Using IF statements
      Umachandar's Bag of Tricks
      Using Temp Tables
      x = @x AND @x IS NOT NULL
      Handling Complex Conditions
   Hybrid Solutions – Using both Static and Dynamic SQL
      Using Views
      Using Inline Table Functions
   Conclusion
   Feedback and Acknowledgements
   Revision History
0 голосов
/ 03 мая 2013

Для максимального значения:

Case when @a > @b or @b is null then @a else @b end.

Это также обрабатывает нули.

Simple.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...