Создание представления SQL, замена переменных фактическими переменными не работает для меня - PullRequest
1 голос
/ 27 июня 2010

Во-первых, позвольте мне поблагодарить вас за помощь!

Теперь я преобразовываю запрос в представление в SQL, поэтому мне нужно заменить все мои переменные на реальные значения. Однако при этом у меня возникают проблемы.

Когда у меня есть

    DECLARE @TweleveAM datetime
    set @TweleveAM = '1900-01-01 00:00:00'
    DECLARE @TweleveThirtyAM datetime
    set @TweleveThirtyAM = '1900-01-01 00:30:00'

    WHEN (cast(segstart as float) - floor(cast(segstart as float))) >= 
(cast(@TweleveAM as float) - floor(cast(@TweleveAM as float))) 
and (cast(segstart as float) - floor(cast(segstart as float))) < 
(cast(@TweleveThirtyAM as float) - floor(cast(@TweleveThirtyAM as float)))
THEN CAST('0' as int)

И вместо этого я использую

    WHEN (cast(segstart as float) - floor(cast(segstart as float))) >= 
(cast(cast('1900-01-01 00:00:00' as datetime)as float) - 
floor(cast(cast('1900-01-01 00:00:00' as datetime) as float))) 
and (cast(segstart as float) - floor(cast(segstart as float))) < 
(cast(cast('1900-01-01 00:00:30' as datetime) as float) - 
floor(cast(cast('1900-01-01 00:00:30' as datetime) as float)))
THEN CAST('0' as int)


ELSE Null End as Interval

Мой запрос выдает NULL, хотя на самом деле данные никогда не NULL.

Что я здесь не так делаю?

Ответы [ 2 ]

3 голосов
/ 27 июня 2010

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

 DECLARE @TweleveThirtyAM datetime
    set @TweleveThirtyAM = '1900-01-01 00:30:00'

Второй имеет 30 секунд после полуночи

'1900-01-01 00:00:30'

Хотя вы все равно должны использовать формат ISO 1900-01-01T00:30:00.000. Если в запросе подставлено правильное значение, оно выглядит как

SELECT
  CASE
    WHEN
      (
        CAST(segstart AS FLOAT) - floor(CAST(segstart AS FLOAT))
      )
      >= (CAST(CAST('1900-01-01T00:00:00.000' AS DATETIME) AS FLOAT) - floor(CAST(CAST('1900-01-01T00:00:00.000' AS DATETIME) AS FLOAT)))
    AND
      (
        CAST(segstart AS FLOAT) - floor(CAST(segstart AS FLOAT))
      )
      < (CAST(CAST('1900-01-01T00:30:00.000' AS DATETIME) AS FLOAT) - floor(CAST(CAST('1900-01-01T00:30:00.000' AS DATETIME) AS FLOAT)))
    THEN CAST('0' as int)
    ELSE NULL
  END AS Interval
FROM T

Это можно упростить до

SELECT
  CASE
    WHEN
      (
        CAST(segstart AS FLOAT) - floor(CAST(segstart AS FLOAT))
      )
      >= 0
    AND
      (
        CAST(segstart AS FLOAT) - floor(CAST(segstart AS FLOAT))
      )
      < 1.0/48
    THEN 0
    ELSE NULL
  END AS Interval
FROM T

Я не думаю, что первая часть может быть ложной, так что ее можно удалить, оставив

SELECT
  CASE
    WHEN
        CAST(segstart AS FLOAT) - floor(CAST(segstart AS FLOAT)) < 1.0/48
    THEN 0
    ELSE NULL
  END AS Interval
FROM T

Что может быть понятнее как

SELECT
  CASE
    WHEN
        DATEPART(HOUR, segstart) = 0 AND DATEPART(MINUTE, segstart  < 30)
    THEN 0
    ELSE NULL
  END AS Interval
FROM T

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

SELECT 2 * DATEPART(HOUR, segstart) +  DATEPART(MINUTE, segstart) / 30 AS Interval
1 голос
/ 27 июня 2010

Похоже, вы используете SQLServer. Вместо того, чтобы приводить ваши datetime в числа с плавающей точкой для вычисления разницы во времени, я предлагаю использовать функцию datediff в SQLServer с аргументом минут или секунд, в зависимости от ситуации.

...