Как сравнить значения столбца с объявленной переменной

Мне задали этот вопрос на собеседовании.

--Without modifying the following code:

DECLARE @StartDateInput SMALLDATETIME = '1/1/2018',
            @EndDateInput SMALLDATETIME = '1/1/2018'

--Modify the following query so that it will return contacts modified at any time on January 1st, 2018
SELECT *
FROM   dbo.Contacts

Я попробовал следующий запрос, но это было неправильно. Я уверен, что я также должен использовать переменную @EndDateInput, но я не знал, как ее использовать. Я не думаю, что это правильный подход к этому в целом.

SELECT *
FROM dbo.Contacts
WHERE  ModifiedDate = SMALLDATETIME

person YHapticY    schedule 07.11.2020    source источник
comment
Моим первым вопросом к ним был бы тип данных столбца ModifiedDate? (Я подозреваю из формулировки, что это временной тип, такой как DATETIME)   -  person Caius Jard    schedule 07.11.2020
comment
Это был тип данных datetime   -  person YHapticY    schedule 07.11.2020


Ответы (2)


Похоже, что вопрос проверяет ваше понимание типов даты и даты и времени, а именно, что дата со временем наступает после даты без времени (если вообще существует такая вещь; большинство вневременных дат считается полночью соответствующей даты , что тоже время.. точно так же, как 1.0 - это то же самое, что и 1, а 1.1 - это после 1.0)

Я бы использовал диапазон:

SELECT *
FROM   dbo.Contacts
WHERE ModifiedDate >= @StartDateInput AND ModifiedDate < DATEADD(DAY, 1, @EndDateInput)

Почему?

  • Это обслуживает дату и время, которые имеют компонент времени.
  • Он не изменяет данные строки (всегда плохая идея, например, приводить миллион дат к дате только для того, чтобы отключить время, каждый раз, когда вы запрашиваете - исключает использование индекса в столбце и является огромной тратой ресурсов) просто выполнить запрос.
  • Он преобразует кажущуюся дату окончания включительно, подразумеваемую тем, что обе переменные @variable одинаковы, в форму, которая позволяет использовать исключительное поведение < (добавляет день, а затем получает строки меньше, чем следующий день, таким образом включая 23:59: 59,999999...)

Единственное, что я хотел бы сказать, это то, что строго спецификация требует записи только за один день, что означает, что вообще не обязательно использовать @EndDateInput. Кажется логичным использовать его, но можно возразить, что если спецификация такова, что этот запрос будет когда-либо возвращаться только один день, переменная @End может быть отброшена, а DATEADD будет выполняться вместо @Start.

person Caius Jard    schedule 07.11.2020
comment
Cast( DateTimeColumn as Date ) распознается оптимизатором запросов как особый случай и может использовать поиск по индексу, что является одним из исключений из правила, согласно которому применение функции к столбцу в предложении where или on исключает использование поиска по индексу. В этом ответе рассматриваются некоторые варианты. Тем не менее, я предпочитаю четкость полуоткрытого интервала, как показано на рисунке. в вашем коде. - person HABO; 07.11.2020

Это говорит в любое время, что означает учитывать компонент времени. В T-SQL единственным надежным способом является использование запроса диапазона ›= и ‹ (эксклюзивный верхний диапазон):

SELECT *
FROM dbo.Contacts
WHERE  ModifiedDate >= @StartDateInput and 
       ModifiedDate < dateadd(d, 1, @EndDateInput);

PS: первоначальное объявление @StartDateInput и @ENDDateInput не является надежным и, вероятно, случайно указывает на 1 января 2018 года. Если бы это было «1/2/2018», тогда это было бы неоднозначно между 2 января и 1 февраля. Лучше использовать канонические строки ODBC и/или строки ISO 8601, например «20180101».

person Cetin Basoz    schedule 07.11.2020