2016-07-01 2 views
-1

Я ищу, чтобы преобразовать даты в SQL (Azure) в целое число, чтобы я мог вычесть обе даты. Формат даты - «ГГГГ-ММ-ДД», и я хочу, чтобы мой оператор case возвращал Null в качестве конечной даты, если существует более 25 дней в месяц (если разница между датой окончания и датой начала равна или больше чем 25). Следующим является мой запрос:SQL-Преобразование даты в SQL для целого числа для оператора case

SELECT DISTINCT 
    [slot machines].[serial number], 
    [slot machine data].[coin in], 
    'End Date' = (CASE 
        WHEN ([slot machine data].[data calendar start date] - [slot machine data].[data calendar end date]) >= 25 
         THEN NULL 
         ELSE [slot machine data].[data calendar end date] 
        END), 
    casino.casino 
FROM 
    [slot machines], [slot machine data], 
    [slot machine configurations], [casino], [Themes Master List] 
+0

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

+0

Я использую Sql Azure. Просто пометили его. – pandoo

+1

[Плохие привычки пинать: использование старинного стиля JOINs] (http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/08/bad-habits-to-kick-using-old-style-joins. aspx) - стиль старого стиля * разделенный запятыми список таблиц * был заменен на * правильный * ANSI 'JOIN' синтаксис в ANSI - ** 92 ** SQL Standard (** более 20 лет ** назад) и его использование не рекомендуется –

ответ

0

Похоже, что вы используете SQL Server. Вобще даты арифметику на одну дату:

(CASE WHEN [slot machine data].[data calendar start date] >= DATEADD(day, -25, [slot machine data].[data calendar end date]) 
     THEN [slot machine data].[data calendar end date] 
END) 

Вам даже не нужен ELSE - NULL возвращается, если нет совпадений.

+0

При ответе на ваш вопрос была получена следующая ошибка: Msg 206, Level 16, State 2, Line 1 Тип столкновения типа операнда: дата несовместима с int – pandoo

1
CASE WHEN DATEDIFF(day,[slot machine data].[data calendar start date],[slot machine data].[data calendar end date]) >= 25 THEN NULL ELSE [slot machine data].[data calendar end date] END 
+0

На всякий случай, когда даты когда-либо были изменены или неправильный порядок в столбцах, я мог бы предложить упаковку ваш DATEDIFF() в АБС (DATEDIFF()), чтобы всегда проверять положительное целое число. Затем по чисто личным предпочтениям я бы переключил my> = 25 на <= 24 и изменил значения в NULL/ELSE, таким образом, если добавлено больше случаев, их немного легче добавить, не испортив потенциально неправильное значение. – Matt

+0

Я понимаю ваше предложение ABS(), но если даты были заменены, тогда возникнут другие проблемы, которые необходимо будет решить, нет? Я имею в виду, что я, вероятно, не хочу, чтобы это возвращалось, если это произошло. Я не согласен с тем, что я имел дело с датами, особенно для параметров, чтобы компенсировать полный 23:59:59 каждого дня, но оставил его, как это было в OP, если бы они что-то принимали во внимание. – scsimon

+1

true Я думаю, вы могли бы захотеть увидеть, когда они будут переключаться, и это будет то, что я буду тестировать в своих собственных наборах данных. Даты, особенно со временем, могут определенно быть самыми сложными несколько раз! И тогда зная, когда вы хотите добавить, что 1 день назад в датиффе или не слишком ... Его почти так же расстраивает, как разделение строки динамически может быть :) – Matt

0

Не то, что я защищаю эту технику, но чтобы проиллюстрировать причины

([slot machine data].[data calendar start date] - [slot machine data].[data calendar end date]) >= 25 

не работает и для получения ошибки в ваш комментарий:

Msg 206, Level 16, State 2, Line 1 Operand type clash: date is incompatible with int 

потому, что один или оба ваших поля даты ([data calendar start date],[data calendar end date]) - это DATE тип данных не такой тип данных, как DATETIME. Если оба поля, где DATETIME, будет работать в вашем случае.

Технически вы могли бы бросить свои столбцы DATETIME и CAST, которые приводят как INT ........

CAST((CAST([slot machine data].[data calendar start date] AS DATETIME) - CAST([slot machine data].[data calendar end date]) AS DATETIME) AS INT) >= 25 

CAST AS INT Последнее необходимо только потому, что вы специально заливке другие значения, если они уже DATETIME вы не должны делать это ......

DATEDIFF() является гораздо более простой способ просто думал, что я хотел бы указать, почему у вас проблемы с вашим кодом.

Прежде всего, можно подумать о том, чтобы использовать ABS(DATEDIFF()), если ваши даты когда-либо будут замешаны до старости/новички и приведут к отрицательному результату. ABS - это абсолютное значение и всегда будет иметь положительное целое число.

пример, чтобы проиллюстрировать возможности делать то, что вы хотите, когда значения DATETIME

DECLARE @StartDate DATE = GETDATE() - 10 
DECLARE @Now DATE = GETDATE() 
DECLARE @StartDateDT DATETIME = GETDATE() - 10 
DECLARE @NowDT DATETIME = GETDATE() 

SELECT 
    CAST(CAST(@Now AS DATETIME) - CAST(@StartDate AS DATETIME) AS INT) 
    ,CAST(@Now AS DATETIME) - CAST(@StartDate AS DATETIME) - 0 
    ,@NowDT - @StartDateDT