Как выбрать true/false на основе значения столбца?
У меня есть таблица со следующими столбцами:
EntityId, EntityName, EntityProfile,.................
Я хочу выбрать столбец Id и Name и true/false на основе значения профиля сущности,
например, возвращаемый набор результатов, как показано ниже, означал бы, что объекты 1 и 2 имеют профили, а 3 нет.
1 Name1 True
2 Name2 True
3 Name3 False
etc.....
Я знаю, что могу сделать это, используя функцию, которая возвращает true/false на основе значения профиля, подобного этому:
SELECT EntityId, EntityName, dbo.EntityHasProfile(EntityId) AS HasProfile FROM Entities
но я возвращаю большой нет. записей и с этим вызовом функции для каждой записи, запрос выполняется очень медленно, и когда я удаляю вызов функции, время выполнения запроса значительно падает.
Так есть другой способ сделать это?
Благодаря
Ответы
Ответ 1
Используйте CASE
. Я бы опубликовал конкретный код, но вам нужно больше информации, чем указано в сообщении, например, тип данных EntityProfile и то, что обычно хранится в нем. Что-то вроде:
CASE WHEN EntityProfile IS NULL THEN 'False' ELSE 'True' END
Изменить - весь оператор SELECT в соответствии с информацией в комментариях:
SELECT EntityID, EntityName,
CASE WHEN EntityProfile IS NULL THEN 'False' ELSE 'True' END AS HasProfile
FROM Entity
В этом случае нет LEFT JOIN...
Ответ 2
Вы можете попробовать что-то вроде
SELECT e.EntityId,
e.EntityName,
CASE
WHEN ep.EntityId IS NULL THEN 'False'
ELSE 'TRUE'
END AS HasProfile
FROM Entities e LEFT JOIN
EntityProfiles ep ON e.EntityID = ep.EntityID
или
SELECT e.EntityId,
e.EntityName,
CASE
WHEN e.EntityProfile IS NULL THEN 'False'
ELSE 'TRUE'
END AS HasProfile
FROM Entities e
Ответ 3
Если способ определения того, имеет ли объект профиль, является детерминированной функцией и не требует доступа к другой таблице, вы можете написать хранимую функцию и определить вычисленное, постоянное поле, которое сохранит это значение для вас, и вам не придется повторно вычислять его снова и снова.
Если вам нужно запросить отдельную таблицу (например, проверить наличие строки), вы все равно можете сделать этот "HasProfile" столбец в таблице сущностей и просто вычислить это поле на регулярной основе, например. каждую ночь или около того. Если у вас есть значение, хранящееся как атомное значение, вам не нужно вычислять каждый раз. Это работает до тех пор, пока этот факт - имеет профиль или нет - не изменяется слишком часто.
Чтобы добавить столбец для проверки того, пустой или нет EntityProfile
, выполните следующие действия:
CREATE FUNCTION CheckHasProfile(@Field VARCHAR(MAX))
RETURNS BIT
WITH SCHEMABINDING
AS BEGIN
DECLARE @Result BIT
IF @Field IS NULL OR LEN(@Field) <= 0
SET @Result = 0
ELSE
SET @Result = 1
RETURN @Result
END
а затем добавьте новый столбец в таблицу Entity
:
ALTER TABLE dbo.Entity
ADD HasProfile AS dbo.CheckHasProfile(EntityProfile) PERSISTED
Теперь у вас есть столбец BIT и он сохраняется, например. не вычисляется каждый раз, чтобы получить доступ к строке, и должен выполнять только штраф!
Ответ 4
Что делает UDF EntityHasProfile()?
Как правило, вы можете сделать что-то подобное с помощью LEFT JOIN:
SELECT EntityId, EntityName, CASE WHEN EntityProfileIs IS NULL THEN 0 ELSE 1 END AS Has Profile
FROM Entities
LEFT JOIN EntityProfiles
ON EntityProfiles.EntityId = Entities.EntityId
Это должно устранить необходимость в дорогостоящем скалярном вызове UDF - по моему опыту, скалярные UDF должны быть последним средством для большинства задач проектирования баз данных в SQL Server - они просто не являются хорошими исполнителями.