Ответ 1
вам нужно закрыть инструкцию case
case when ... then ... else ... end
Я пытаюсь заставить этот код работать, в отдельности работают две части кода (в части WHEN
и в части ELSE
), но при использовании в этом выражении CASE
я получаю сообщение об ошибке
"Неверный синтаксис рядом с" CAST ", ожидаемый" AS ". ошибка.
В принципе, если код операторов WHEN
равен или больше 24, то используйте оператор THEN
, если его значение меньше 24, затем используйте оператор ELSE
.
Я не могу заставить это работать после того, как в течение нескольких часов будет указано какое-либо указание на то, куда я иду не так.
SELECT CASE
WHEN
(convert(float,datediff(mi, start_work, end_work))/60) >= '24'
THEN
(convert(float,datediff(mi, start_work, end_work))/60)
ELSE
(CAST(convert(varchar(2), dateadd(minute, datediff(minute, start_time, end_time), 0), 114)
* 60 + RIGHT (convert(varchar(5), dateadd(minute, datediff(minute, start_time, end_time), 0), 114),
CASE WHEN CHARINDEX(':',convert(varchar(5), dateadd(minute, datediff(minute, start_time, end_time), 0), 114)) > 0
THEN LEN(convert(varchar(5), dateadd(minute, datediff(minute, start_time, end_time), 0), 114))-3
ELSE LEN(convert(varchar(5), dateadd(minute, datediff(minute, start_time, end_time), 0), 114))
END) AS decimal) / 60
FROM NDB.dbo.statusa
INNER JOIN NDB.dbo.details ON statusa.vkey = details.vkey
INNER JOIN NDB.dbo.chegu ON statusa.ckey = NDB.dbo.chegu.gkey
WHERE start_time!= end_time AND string1 = Visit_Id and NDB.dbo.chegu.name = 'loft'
AS [Working]
вам нужно закрыть инструкцию case
case when ... then ... else ... end
Должно существовать END
перед предложением FROM
, и вы также должны удалить (
до CAST
.
Есть закрывающая закрывающая скобка.
SELECT CASE
WHEN
(convert(float,datediff(mi, start_work, end_work))/60) >= '24'
THEN
(convert(float,datediff(mi, start_work, end_work))/60)
ELSE
(CAST(convert(varchar(2), dateadd(minute, datediff(minute, start_time, end_time), 0), 114)
* 60 + RIGHT (convert(varchar(5), dateadd(minute, datediff(minute, start_time, end_time), 0), 114),
CASE WHEN CHARINDEX(':',convert(varchar(5), dateadd(minute, datediff(minute, start_time, end_time), 0), 114)) > 0
THEN LEN(convert(varchar(5), dateadd(minute, datediff(minute, start_time, end_time), 0), 114))-3
ELSE LEN(convert(varchar(5), dateadd(minute, datediff(minute, start_time, end_time), 0), 114))
END) AS decimal) / 60)
Незакрытые круглые скобки и оператор case нуждаются в END.
SELECT CASE
WHEN (convert(FLOAT, datediff(mi, start_work, end_work)) / 60) >= '24'
THEN (convert(FLOAT, datediff(mi, start_work, end_work)) / 60)
ELSE CAST(convert(VARCHAR(2), dateadd(minute, datediff(minute, start_time, end_time), 0), 114) * 60
+ RIGHT(
convert(VARCHAR(5), dateadd(minute, datediff(minute, start_time, end_time), 0), 114),
CASE
WHEN CHARINDEX(':', convert(VARCHAR(5), dateadd(minute, datediff(minute, start_time, end_time), 0), 114)) > 0
THEN LEN(convert(VARCHAR(5), dateadd(minute, datediff(minute, start_time, end_time), 0), 114)) - 3
ELSE LEN(convert(VARCHAR(5), dateadd(minute, datediff(minute, start_time, end_time), 0), 114))
END
) AS DECIMAL) / 60
END
FROM NDB.dbo.statusa
INNER JOIN NDB.dbo.details
ON statusa.vkey = details.vkey
INNER JOIN NDB.dbo.chegu
ON statusa.ckey = NDB.dbo.chegu.gkey
WHERE start_time != end_time
AND string1 = Visit_Id
AND NDB.dbo.chegu.NAME = 'loft' AS [Working]
Я понял, что этот ответ слишком поздно для награды. Но ваш script ПУТЬ слишком длинный. Это будет делать то же самое, что вы пытаетесь достичь, исправляя ошибку в вашем коде, просто исправляет плохой код:
SELECT
datediff(mi, 0, end_time - start_time)/60.0%24
FROM
....
Две основные формулировки для выражения CASE 1) Простые выражения CASE Простое выражение CASE проверяет одно выражение на несколько значений. В выражении SELECT простое выражение CASE допускает только проверку равенства; других сравнений не делается. Простое выражение CASE работает, сравнивая первое выражение с выражением в каждом предложении WHEN для эквивалентности. Если эти выражения эквивалентны, выражение в предложении THEN будет возвращено.
2) Искаженные выражения CASE Выбранное выражение CASE позволяет операторам сравнения и использовать AND и/или OR между каждым булевым выражением. Простое выражение CASE проверяет только эквивалентные значения и не может содержать булевы выражения. Ниже приведен базовый синтаксис для найденного выражения CASE:
Подробнее здесь: http://blog.sqlauthority.com/2007/04/14/sql-server-case-statementexpression-examples-and-explanation/
В коде есть 2 ошибки.
Первый, у вас есть дополнительная скобка перед CAST, которая не нужна (и не закрывается когда-либо). Изменение
(CAST(convert(varchar(2), dateadd(minute, datediff(minute, start_time, end_time), 0), 114)
к
CAST(convert(varchar(2), dateadd(minute, datediff(minute, start_time, end_time), 0), 114)
Второе: Добавить END в конце оператора CASE перед ключевым словом FROM (как указано выше также в @gefei). Ваш последний код должен выглядеть следующим образом:
SELECT CASE
WHEN
(convert(float,datediff(mi, start_work, end_work))/60) >= '24'
THEN
(convert(float,datediff(mi, start_work, end_work))/60)
ELSE
CAST(convert(varchar(2), dateadd(minute, datediff(minute, start_time, end_time), 0), 114)
* 60 + RIGHT (convert(varchar(5), dateadd(minute, datediff(minute, start_time, end_time), 0), 114),
CASE WHEN CHARINDEX(':',convert(varchar(5), dateadd(minute, datediff(minute, start_time, end_time), 0), 114)) > 0
THEN LEN(convert(varchar(5), dateadd(minute, datediff(minute, start_time, end_time), 0), 114))-3
ELSE LEN(convert(varchar(5), dateadd(minute, datediff(minute, start_time, end_time), 0), 114))
END) AS decimal) / 60
END
FROM NDB.dbo.statusa
INNER JOIN NDB.dbo.details ON statusa.vkey = details.vkey
INNER JOIN NDB.dbo.chegu ON statusa.ckey = NDB.dbo.chegu.gkey
WHERE start_time!= end_time AND string1 = Visit_Id and NDB.dbo.chegu.name = 'loft'
AS [Working]
Функция RIGHT() не имеет второго параметра
RIGHT (convert(varchar(5), dateadd(minute, datediff(minute, start_time, end_time), 0), 114),
или: вы пропустили конечную скобку за AS decimal
END ) AS decimal ) ) / 60
Здесь скорректированная версия вашего кода:
SELECT CASE
WHEN
(convert(float,datediff(mi, start_work, end_work))/60) >= '24'
THEN
(convert(float,datediff(mi, start_work, end_work))/60)
ELSE
(CAST(convert(varchar(2), dateadd(minute, datediff(minute, start_time, end_time), 0), 114)
* 60 + RIGHT (convert(varchar(5), dateadd(minute, datediff(minute, start_time, end_time), 0), 114),
CASE WHEN CHARINDEX(':',convert(varchar(5), dateadd(minute, datediff(minute, start_time, end_time), 0), 114)) > 0
THEN LEN(convert(varchar(5), dateadd(minute, datediff(minute, start_time, end_time), 0), 114))-3
ELSE LEN(convert(varchar(5), dateadd(minute, datediff(minute, start_time, end_time), 0), 114))
END) AS decimal) / 60
END
AS [Working]
FROM NDB.dbo.statusa INNER JOIN NDB.dbo.details ON statusa.vkey = details.vkey INNER JOIN NDB.dbo.chegu ON statusa.ckey = NDB.dbo.chegu.gkey WHERE start_time!= end_time AND string1 = Visit_Id and NDB.dbo.chegu.name = 'loft'
В основном у вас был отсутствующий END во внешнем выражении SELECT..CASE, а выбранный псевдоним столбца [Working] был ошибочно помещен в конец запроса, а не в предложение select запроса.