Преобразовать целое число во время, затем запросить, превышает ли текущее время это целое число

#sql #sql-server

#sql #sql-сервер

Вопрос:

Мне поручено разработать систему доставки на нашем предприятии. В настоящее время мы получаем заказы от клиента со временем доставки грузовиком в военном формате в виде целого числа. Если клиент получил два заказа сегодня, например, в 6: 30 утра и 17: 00 вечера, он покажет два заказа с «0630» и «1700» в столбце int. Мне нужно сначала преобразовать это время int в военное время, а затем выполнить проверку времени системной даты, чтобы увидеть, не превысил ли этот порядок текущее время. Итак, если сейчас 7:00 утра, мне нужно, чтобы 6:30 утра просто больше не отображались в запросе.

Ссылка на SQL-манипуляцию со схемой: http://sqlfiddle.com /#!18/b52be

Я не уверен, как преобразовать целое число в читаемый формат времени. В идеале, по крайней мере, я думаю, если бы я мог просто перевести его в формат текущего времени даты, я мог бы просто добавить в предложение where, где if it> getdate() не отображается, но я не совсем уверен. Любая помощь была бы высоко оценена!

Ответ №1:

Предполагая, что я правильно понимаю ваше требование, тогда вы могли бы преобразовать int значение в time , как я сделал в VALUES предложении, а затем сослаться на это в WHERE . Обратите внимание, однако, что это повлияет на производительность запроса:

 SELECT *
FROM orders o
     CROSS APPLY (VALUES(CONVERT(time(0),STUFF(RIGHT('0000'   CONVERT(varchar(4), pickup),4),3,0,':')))) V(pickuptime)
WHERE o.shipdate >= CONVERT(date, GETDATE())
  AND v.pickuptime > CONVERT(time(0), GETDATE());
  

Работаем другим способом и преобразуем текущее datetime в int (что, вероятно, будет работать намного лучше):

 SELECT *
FROM orders o
     CROSS APPLY(VALUES(CONVERT(int,REPLACE(LEFT(CONVERT(varchar(8),CONVERT(time,GETDATE()),109),5),':',''))))V(GD)
WHERE o.shipdate >= CONVERT(date, GETDATE())
  AND o.pickup > V.GD;
  

Комментарии:

1. Хм, так, может быть, мы могли бы поработать в обратном направлении и преобразовать getdate() в int, чтобы, возможно, воспользоваться индексами?

2. Да, я думал, что @GeorgeMenoutis

3. @Larnu Не могли бы вы кратко рассказать мне о перекрестном применении? Я никогда не видел этого раньше, но я также довольно любитель в этой области.

4. ПЕРЕКРЕСТНОЕ ПРИМЕНЕНИЕ — это потрясающе! Проверьте некоторые интересные функции, которые он предоставляет здесь: bradsruminations.blogspot.com/2011/04 /…

5. CROSS APPLY обычно используется с функциями табличных значений, @DaveHolt. В отличие от JOIN , для этого не требуется ON предложение (фактически оно не поддерживается ON , поскольку обычно вы используете коррелированный запрос). Кроме того, в отличие от JOIN подзапроса с подзапросом вы можете JOIN ссылаться на объекты вне TOP 1 ; Я нахожу эту конкретную его часть бесценной с такими понятиями, как «,, объединения»). В этом случае я использую VALUES предложение с выражением, которое (в конце) преобразует значение pickup в time или GETDATE() в целочисленное представление текущего времени (в зависимости от того, какой запрос вы просматриваете).

Ответ №2:

Я бы посоветовал вам сохранять даты в datetime поле, вместо того, чтобы хранить их в int поле. Причина в том, что сегодня вы получаете параметры в формате military, а завтра вы можете получить в другом формате. Это не должно определять ваш формат хранения. Ваш формат хранения должен не зависеть от способа запроса к нему.

Как только вы сохраните даты в стандартном datetimeformat , запрос становится очень простым. Это не ответ на ваш вопрос. Ответ уже предоставлен @Larnu. Я просто даю другую перспективу.

 DECLARE @pickupDateTimeCutOff DATETIME = GETDATE()
SELECT * FROM orders WHERE  vpickupDateTime < @pickupDateTimeCutOff 
  

Комментарии:

1. Спасибо за ответ. Я не собираюсь говорить, что это невозможно сделать, но на самом деле я не генерирую заказы, это то, как мы получаем это от наших клиентов. Для меня не имеет смысла, почему они делают это таким образом, но я должен попытаться адаптироваться к их требованиям.

2. @DaveHolt, понял. Я понимаю. спасибо за ваш ответ.

Ответ №3:

Просто добавьте время к вашей дате:

 SELECT partnum, DATEADD(mi, pickup%100, DATEADD(hh, pickup/100, CONVERT(DATETIME, shipdate)))
FROM orders
WHERE DATEADD(mi, pickup%100, DATEADD(hh, pickup/100, CONVERT(DATETIME, shipdate))) > GETDATE()