#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()