将 INT 转换为 BIT 的最佳方法

43

我有一个 INT 类型的列,如果其中包含 1,我想选择 1;否则选择 0。我知道这样做的唯一方法是使用 CASE 语句:

CASE WHEN val=1 THEN 1 ELSE 0

有哪些其他方法可以达到相同的结果?


2
DECLARE @r VARCHAR(10)='1' SELECT CAST(@r AS BIT) - Royi Namir
1
@RoyiNamir:整数但是字符串 ;) - dani herrera
1
@danihp 如果val是整数,也将有效 :-) - Royi Namir
1
@RoyiNamir...只是为了回答OP的问题。 - dani herrera
1
你可以尝试使用SELECT CAST(val AS bit)。 - Snorre
显示剩余4条评论
4个回答

53

SQL SERVER 2012:

SELECT CAST(IIF ( field = 1, 1, 0 ) AS BIT) FROM table
否则:
SELECT CAST(CASE field WHEN 1 THEN 1 ELSE 0 END AS BIT) From table

2
我认为最佳实践是检查 field 是否等于 0。 - Greg
@Greg 这并不能解决原帖中的问题,因为问题特别在于测试数值是否为1。 - Stewart

19

1
OP的问题说“如果包含1则选择1,否则选择0”。因此,这将把除0或1之外的任何值转换为错误的值。 - Stewart
你是正确的。 :) 我读了标题,显然只是匆匆浏览了问题。 - phokus

4

转换很简单,只要是1或0就可以直接赋值,无需进行强制转换。

当您声明一个变量时,也是同样的道理吧?

@declare @myBit bit =1;

然而,当你想要对整数执行更有用的操作,例如位图比较时,事情就变得更加有趣。你可以比较两个整数,并根据定义的方式返回一个基于位的比特。
让我尝试形象化说明

    00000001=1
    00000010=2
    00000011=3
==============
    FFFFFFTT

如果您有一个1,则该值变为True。

实际上,对于两个值的位图比较就像映射光栅一样,您可以在字节级别上使用0 + 1来分组多个值。

如上所示,1“在”3中,2“也在”3中。

请查看下面的TSQL单元测试示例。

declare @notSet     int =0
      , @CanView    int =1 
      , @CanEdit    int =2 
      , @CanSubmit  int =4 
      , @CanApprove int =8
      , @CanDelete  int =16; 

declare @contributor int = @CanView | @CanEdit | @CanSubmit     --> Can't delete
       , @moderator  int = @CanView | @CanEdit | @CanDelete     --> not allowed to sumbit
       , @admin      int = @CanView | @CanEdit | @CanSubmit | @CanApprove | @CanDelete;--> can do all

SELECT TEST='A admin can Submit'            , RESULT= iif(@admin     & @CanSubmit = @CanSubmit,'TRUE','FALSE')
UNION ALL
SELECT TEST='A Moderator may not Submit'    , RESULT= iif(@moderator & @CanSubmit = @CanSubmit,'FALSE','TRUE')
UNION ALL
SELECT TEST='A Contributer may not delete'  , RESULT= iif(@contributor & @CanDelete = @CanDelete,'FALSE','TRUE')
UNION ALL
SELECT TEST='A Moderator may delete'        , RESULT= iif(@moderator & @CanDelete = @CanDelete,'TRUE','FALSE')

您可以使用位运算符"| "将值组合在一起,例如1|2 = 3,1|1 = 1,不要将"|"与"+"混淆,因为它不总是有效的。;-)
举个例子,错误的方式是 @CanView + @CanView,正确的方式是 @CanView | @CanView 将仍然是 @CanView。
在SQL中试试吧。
SELECT (1|1), (1+1) 

以下是一些 C# 代码,希望它能帮助那些想要在代码和数据库中保存和使用枚举的人。
假设你有一个这样的枚举和类:
[Flags] public enum Rights { notSet =0 , CanView =1 , CanEdit =2 , CanSubmit =4 , CanApprove =8 , CanDelete =16 }
public class User
{
  public Rights Permission {get;set}
}

...
// user can change his own posts
var user = new User();
user.Permission = Rights.CanView | Rights.CanEdit | Rights.CanDelete ;

现在您可以将权限存储在数据库中,并使用以下方法之一读取该值,其中您可以比较一个或比较多个:

var result = user.Permission & Rights.CanView  == Rights.CanView;
var canChange = ((user.Permission & (Rights.CanView  | Rights.CanEdit | Rights.CanDelete)) != 0);

所以,已经往返于数据库之间,希望你找到了你要的内容。

编程愉快,

沃尔特


这将把除了0或1之外的任何值转换为1,而不是OP所要求的0。 - Stewart

1
这里有另一种解决方案。没有使用caseiif
select ~cast(sign(abs(@i - 1)) as bit)

但是当 @i = -2147483648 时是无法使用的。因此,您需要将其转换为 bigint


1
你所需要的是这个:SELECT~cast(val-1as bit) - t-clausen.dk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接