Подтвердить что ты не робот

Как выбрать 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

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

Так есть другой способ сделать это? Благодаря

4b9b3361

Ответ 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 - они просто не являются хорошими исполнителями.