#sql #sql-server
#sql #sql-сервер
Вопрос:
Я пытался написать запрос для извлечения данных из таблицы при условии, что предложение where имеет регистр, но мне нужно поместить or в оператор case, но я не могу найти решение:
Ниже приведен мой запрос
SELECT WFET.InstanceID,
WFI.SomeID
FROM [SOME_Instance] WFI
INNER JOIN [SomeTracker] WFET ON WFI.InstanceID = WFET.InstanceID
INNER JOIN SOMEPROP_INSTANCE WFPI ON WFET.ItemID = WFPI.WIID
WHERE WFI.InstanceID NOT IN (SELECT WFTT.InstanceID
FROM [SomeTracker] WFTT
INNER JOIN [dbo].[SomeItems_Instance] WFII ON WFII.ITemID = WFTT.ItemID
INNER JOIN SomeActivities WFA ON WFII.ActivityType = WFA.ActivityTypeID
WHERE WFTT.Status IN (CASE WHEN WFA.ActivityType <> 'Conn' THEN ('Running','Pending') ELSE 'Pending' END))
AND WFI.Status = 'Running'
AND WFPI.PropertyType <> 'Last'
GROUP BY WFET.InstanceID,
WFI.SomeID;
Комментарии:
1. Это выражение case, то есть оно возвращает одно атомарное значение. Таким образом, вы не можете использовать его таким образом.
2. Пожалуйста, также не КРИЧИТЕ; мы прекрасно можем прочитать ваши внутренние слова.
3. хорошо, но есть ли какой-либо способ, с помощью которого я могу организовать свой запрос так, чтобы я мог указать два значения
4. SQL с выравниванием по левому краю так сложно читать и писать.
5.
CASE
Выражение возвращает скалярное значение.THEN ('Running','Pending')
не имеет смысла, поскольку это список значений.THEN
Может возвращать только 1 значение, а не много.
Ответ №1:
Вы можете упростить where
логику до:
WHERE WFTT.Status = 'Pending' OR
(WFA.ActivityType <> 'Conn' AND WFIT.Status = 'Running')
Ответ №2:
Перефразируйте предложение where в подзапросе как:
WHERE
(WFA.ActivityType <> 'Conn' AND WFTT.Status IN ('Running','Pending')) OR
WFA.ActivityType = 'Conn' AND WFTT.Status = 'Pending'
Ваше использование CASE
выражений было неправильным, поскольку они должны генерировать одно скалярное значение. CASE
Выражение не может сгенерировать кортеж, но мы все равно можем выразить нужную вам логику.
Полный код:
WHERE WFI.InstanceID NOT IN (SELECT WFTT.InstanceID
FROM [SomeTracker] WFTT
INNER JOIN [dbo].[SomeItems_Instance] WFII
ON WFII.ITemID = WFTT.ItemID
INNER JOIN SomeActivities WFA
ON WFII.ActivityType = WFA.ActivityTypeID
WHERE
WFA.ActivityType <> 'Conn' AND
WFTT.Status IN ('Running','Pending') OR
WFA.ActivityType = 'Conn' AND
WFTT.Status = 'Pending')
Ответ №3:
CASE
Выражение возвращает одно значение в зависимости от логических выражений. Оно не может вернуть кортеж. И мы обычно не используем CASE
в WHERE
предложении в любом случае, потому WHERE
что само предложение генерирует логическое значение. Вместо этого мы используем AND
и OR
для описания желаемых ограничений.
Ваше выражение
WHERE WFTT.Status IN (CASE WHEN WFA.ActivityType <> 'Conn'
THEN ('Running','Pending') ELSE 'Pending' END))
будет записано как
WHERE WFTT.Status = 'Pending'
OR (WFA.ActivityType <> 'Conn' AND WFTT.Status = 'Running')