Как я могу сравнить время в SQL Server?

try:

apt-get install openssh-client

вызвать sftp это сервис из SSH (безопасный FTP)

58
задан Grandtour 22 November 2018 в 09:53
поделиться

10 ответов

Ваше сравнение будет работать, но оно будет медленным, потому что даты преобразуются в строку для каждой строки. Чтобы эффективно сравнить две части времени, попробуйте:

declare @first datetime
set @first = '2009-04-30 19:47:16.123'
declare @second datetime
set @second = '2009-04-10 19:47:16.123'

select (cast(@first as float) - floor(cast(@first as float))) -
       (cast(@second as float) - floor(cast(@second as float)))
       as Difference

Длинное объяснение: дата на сервере SQL сохраняется как число с плавающей запятой. Цифры перед десятичной запятой представляют дату. Цифры после десятичной точки представляют время.

Итак, вот пример даты:

declare @mydate datetime
set @mydate = '2009-04-30 19:47:16.123'

Давайте преобразуем ее в число с плавающей точкой:

declare @myfloat float
set @myfloat = cast(@mydate as float)
select @myfloat
-- Shows 39931,8244921682

Теперь возьмем часть после цифры, то есть время:

set @myfloat = @myfloat - floor(@myfloat) 
select @myfloat
-- Shows 0,824492168212601

Преобразование обратно к дате и времени:

declare @mytime datetime
set @mytime = convert(datetime,@myfloat)
select @mytime
-- Shows 1900-01-01 19:47:16.123

1900-01-01 - это просто «нулевая» дата; Вы можете отобразить часть времени с помощью convert, указав, например, формат 108, который является просто временем:

select convert(varchar(32),@mytime,108)
-- Shows 19:47:16

Преобразования между datetime и float довольно быстрые, потому что они в основном хранятся одинаковым образом.

75
ответ дан 24 November 2019 в 18:48
поделиться

Одна (возможно небольшая) проблема, которую я отметил с решениями до сих пор, заключается в том, что всем им, кажется, требуется вызов функции для обработки сравнение. Это означает, что механизм запросов должен будет выполнить полное сканирование таблицы, чтобы найти строки, которые вы ищете, и не сможет использовать индекс. Если таблица не станет особенно большой, это, вероятно, не окажет отрицательного влияния (и вы можете с радостью проигнорировать этот ответ).

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

Я знаю, что вы заявили, что не хотите сравнивать часть даты - но есть ли фактическая дата, хранящаяся в столбце datetime, или вы используете ее для хранения только времени? Если последнее, вы можете использовать простой оператор сравнения, и это сократит использование ЦП и позволит механизму запросов использовать статистику и индексы (если они есть) для оптимизации запроса.

Если, однако, столбец datetime используется для хранения как даты, так и времени события это явно не сработает. В этом случае, если вы можете изменить приложение и структуру таблицы, разделите дату и время на два отдельных столбца datetime или создайте индексированное представление, которое выбирает все (соответствующие) столбцы исходной таблицы, и еще один столбец, содержащий элемент времени, который вы хотите найти (используйте любой из предыдущих ответов, чтобы вычислить это) - и измените приложение, чтобы вместо этого запросить представление.

это явно не сработает. В этом случае, если вы можете изменить приложение и структуру таблицы, разделите дату и время на два отдельных столбца datetime или создайте индексированное представление, которое выбирает все (соответствующие) столбцы исходной таблицы, и еще один столбец, содержащий элемент времени, который вы хотите найти (используйте любой из предыдущих ответов, чтобы вычислить это) - и измените приложение, чтобы вместо этого запросить представление.

это явно не сработает. В этом случае, если вы можете изменить приложение и структуру таблицы, разделите дату и время на два отдельных столбца datetime или создайте индексированное представление, которое выбирает все (соответствующие) столбцы исходной таблицы, и еще один столбец, содержащий элемент времени, который вы хотите найти (используйте любой из предыдущих ответов, чтобы вычислить это) - и измените приложение, чтобы вместо этого запросить представление.

3
ответ дан 24 November 2019 в 18:48
поделиться

Если вы используете SQL Server 2008, вы можете сделать это:

WHERE CONVERT(time(0), startHour) >= CONVERT(time(0), @startTime)

Вот полный тест:

DECLARE @tbEvents TABLE (
    timeEvent   int      IDENTITY,
    startHour   datetime
)

INSERT INTO @tbEvents (startHour) SELECT DATEADD(hh, 0, GETDATE())
INSERT INTO @tbEvents (startHour) SELECT DATEADD(hh, 1, GETDATE())
INSERT INTO @tbEvents (startHour) SELECT DATEADD(hh, 2, GETDATE())
INSERT INTO @tbEvents (startHour) SELECT DATEADD(hh, 3, GETDATE())
INSERT INTO @tbEvents (startHour) SELECT DATEADD(hh, 4, GETDATE())
INSERT INTO @tbEvents (startHour) SELECT DATEADD(hh, 5, GETDATE())

--SELECT * FROM @tbEvents

DECLARE @startTime  datetime

SET @startTime = DATEADD(mi, 65, GETDATE())

SELECT
    timeEvent,
    CONVERT(time(0), startHour)  AS 'startHour',
    CONVERT(time(0), @startTime) AS '@startTime'
FROM @tbEvents
WHERE CONVERT(time(0), startHour) >= CONVERT(time(0), @startTime)
13
ответ дан 24 November 2019 в 18:48
поделиться
convert(varchar(5), thedate, 108) between @leftTime and @rightTime

Объяснение:

если у вас есть varchar (5) , вы получите ЧЧ: мм

, если у вас есть varchar (8) вы получаете ЧЧ: мм сс

108 получает только время из даты SQL

@leftTime и @rightTime - две переменные для сравнения

19
ответ дан 24 November 2019 в 18:48
поделиться

Добавление к другим ответам :

Вы можете создать функцию для обрезки даты от даты и времени

CREATE FUNCTION dbo.f_trimdate (@dat datetime) RETURNS DATETIME AS BEGIN
    RETURN CONVERT(DATETIME, CONVERT(FLOAT, @dat) - CONVERT(INT, @dat))
END

. Итак, это:

DECLARE @dat DATETIME
SELECT @dat = '20080201 02:25:46.000'
SELECT dbo.f_trimdate(@dat)

Вернет 1900-01-01 02: 25: 46.000

2
ответ дан 24 November 2019 в 18:48
поделиться

Я не люблю полагаться на внутренние компоненты хранилища (эта дата-время - это число с плавающей точкой с целым числом = день, а дробное = время), но я делаю то же самое, что и ответ Джонни Д. Кано. Это способ, которым все известные мне разработчики db делают это. Определенно не конвертировать в строку. Если вам нужно избегать обработки как float / int, то лучший вариант - извлечь часы / минуты / секунды / миллисекунды с помощью DatePart ()

1
ответ дан 24 November 2019 в 18:48
поделиться

Я предполагаю, что ваш столбец startHour и переменная @startHour имеют значение DATETIME; В этом случае вы должны преобразовать в строку:

SELECT timeEvent
FROM tbEvents
WHERE convert(VARCHAR(8), startHour, 8) >= convert(VARCHAR(8), @startHour, 8)
0
ответ дан 24 November 2019 в 18:48
поделиться

Я полагаю, вы хотите использовать DATEPART ('час', datetime) .

Ссылка здесь:

http://msdn.microsoft.com /en-us/library/ms174420.aspx

1
ответ дан 24 November 2019 в 18:48
поделиться
SELECT timeEvent 
  FROM tbEvents 
 WHERE CONVERT(VARCHAR,startHour,108) >= '01:01:01'

Это указывает SQL Server преобразовать текущую дату / время в varchar, используя стиль 108, то есть «чч: мм: сс». Вы также можете заменить "01: 01: 01", при необходимости преобразовав другое значение.

1
ответ дан 24 November 2019 в 18:48
поделиться

Использовать функцию Datepart: DATEPART (datepart, date)

Например #

SELECT DatePart (@YourVar, hh) * 60) + DatePart (@YourVar, mi) * 60)

Это даст вам общее время дня в минутах, что упрощает сравнение.

Вы можете использовать DateDiff, если ваши даты будут такими же, иначе вы ' Вам нужно будет вычеркнуть дату, как указано выше

2
ответ дан 24 November 2019 в 18:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: