如何根据列值选择true / false?

时间:2010-03-07 16:04:59

标签: sql-server

我有一个包含以下列的表: 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

但是我回来了一个大号。记录和用这个函数调用每条记录,查询很慢,当我删除函数调用时,查询执行时间明显下降。

那么还有另一种方法吗? 感谢

6 个答案:

答案 0 :(得分:95)

使用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 ......

答案 1 :(得分:7)

您可以尝试类似

的内容
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

答案 2 :(得分:4)

如果确定实体是否具有配置文件的方式是确定性函数,并且不需要对另一个表的任何访问,则可以编写存储函数并定义计算的持久字段,该字段将存储该值对你而言,不必一遍又一遍地重新计算它。

如果您需要查询单独的表格(例如检查行的存在),您仍然可以将此“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列并且它是持久的,例如每次访问该行时都不会计算,并且应该执行得很好!

答案 3 :(得分:1)

也许为时已晚,但是当我使用.NET架构时,我会将0/1转换成数据类型最终变为True / False:

SELECT   EntityId, 
         EntityName, 
         CASE 
            WHEN EntityProfileIs IS NULL 
            THEN CAST(0 as bit) 
            ELSE CAST(1 as bit) END AS HasProfile
FROM      Entities
LEFT JOIN EntityProfiles ON EntityProfiles.EntityId = Entities.EntityId`

答案 4 :(得分:0)

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中大多数数据库设计问题的最后手段 - 它们根本不是表现良好的。

答案 5 :(得分:0)

至少在Postgres中,您可以使用以下语句:

Uncaught TypeError: Cannot read property 'number' of undefined