【问题标题】:T-SQL convert INT to BOOLEAN arrayT-SQL 将 INT 转换为 BOOLEAN 数组
【发布时间】:2018-10-03 00:50:55
【问题描述】:

我有一个 int 类型的数据(INT 数字,例如 15)。要将其转换为 5 位布尔数组,它将变为 [1,1,1,1,0]

我试过了

SELECT CAST(15 AS binary(5))

但我得到的是一个十六进制值:

0x0000000F

我希望能够选择相应的位,所以它需要是一个布尔数组。

感谢您的帮助

【问题讨论】:

标签: arrays sql-server tsql int boolean


【解决方案1】:

两步过程:首先将 Int 转换为二进制流,然后将其转换为 varchar 并在每个字符出现后添加零。 由于您总是希望长度为 5,因此我也包含了该部分。

这将对您有所帮助:

declare @intvalue int
set @intvalue=15
--Convert Int to Binary Stream
declare @result varchar(64)
declare @i int
select @i = 64, @result = ''
while @i>0
  begin
    select @result=convert(char(1), @intvalue % 2)+@result
    select @intvalue = convert(int, (@intvalue / 2)), @i=@i-1
  end

DECLARE @Char VARCHAR(800) = RIGHT(@result,5)  --TRIM leading zeros and store binary stream as varchar (length of 5)
--Add comma(,) after every  character
DECLARE @TotalChar INT = LEN(@Char)
DECLARE @Counter INT = @TotalChar

WHILE @Counter >= 1
BEGIN

    IF @Counter % 1 = 0 AND @Counter + 1 <= @TotalChar
    BEGIN
        SET @Char = STUFF(@Char, @Counter + 1, 0, ', ')
    END

    SET @Counter = @Counter - 1
END

SELECT @Char --Final output

【讨论】:

    【解决方案2】:

    SQL Server 不是为按位查询而构建的,但有bitwise operators

    如果您更频繁地需要它,您可以创建一个位图表并将其保存在您的数据库中。不需要太多空间,可能很帅......

    DECLARE @bitmaptable TABLE(BitNr INT,IntValue INT,Bitmap BINARY(4),InvertedBitMap BINARY(4));
    
    WITH Numbers AS
    (
        SELECT TOP 33 CAST(ROW_NUMBER() OVER(ORDER BY (SELECT NULL))-1 AS bigint) AS Nr
        FROM master..spt_values
    )
    INSERT INTO @bitmaptable(BitNr,IntValue,BitMap,InvertedBitMap)
    SELECT CASE WHEN Nr=32 THEN -1 ELSE Nr END
          ,CAST(CAST(pwd2 AS BINARY(4)) AS int)
          ,CAST(pwd2 AS BINARY(4))
          ,pwd2 ^ 0xFFFFFFFF
    FROM Numbers
    CROSS APPLY(SELECT POWER(CAST(2 AS BIGINT),Nr) AS pwd2) AS A;
    

    结果(带有-1 的最后一行是nothing set bitmap

    +-------+-------------+------------+----------------+
    | BitNr | IntValue    | Bitmap     | InvertedBitMap |
    +-------+-------------+------------+----------------+
    | 0     | 1           | 0x00000001 | 0xFFFFFFFE     |
    +-------+-------------+------------+----------------+
    | 1     | 2           | 0x00000002 | 0xFFFFFFFD     |
    +-------+-------------+------------+----------------+
    | 2     | 4           | 0x00000004 | 0xFFFFFFFB     |
    +-------+-------------+------------+----------------+
    | 3     | 8           | 0x00000008 | 0xFFFFFFF7     |
    +-------+-------------+------------+----------------+
    | 4     | 16          | 0x00000010 | 0xFFFFFFEF     |
    +-------+-------------+------------+----------------+
    | 5     | 32          | 0x00000020 | 0xFFFFFFDF     |
    +-------+-------------+------------+----------------+
    | 6     | 64          | 0x00000040 | 0xFFFFFFBF     |
    +-------+-------------+------------+----------------+
    | 7     | 128         | 0x00000080 | 0xFFFFFF7F     |
    +-------+-------------+------------+----------------+
    | 8     | 256         | 0x00000100 | 0xFFFFFEFF     |
    +-------+-------------+------------+----------------+
    | 9     | 512         | 0x00000200 | 0xFFFFFDFF     |
    +-------+-------------+------------+----------------+
    | 10    | 1024        | 0x00000400 | 0xFFFFFBFF     |
    +-------+-------------+------------+----------------+
    | 11    | 2048        | 0x00000800 | 0xFFFFF7FF     |
    +-------+-------------+------------+----------------+
    | 12    | 4096        | 0x00001000 | 0xFFFFEFFF     |
    +-------+-------------+------------+----------------+
    | 13    | 8192        | 0x00002000 | 0xFFFFDFFF     |
    +-------+-------------+------------+----------------+
    | 14    | 16384       | 0x00004000 | 0xFFFFBFFF     |
    +-------+-------------+------------+----------------+
    | 15    | 32768       | 0x00008000 | 0xFFFF7FFF     |
    +-------+-------------+------------+----------------+
    | 16    | 65536       | 0x00010000 | 0xFFFEFFFF     |
    +-------+-------------+------------+----------------+
    | 17    | 131072      | 0x00020000 | 0xFFFDFFFF     |
    +-------+-------------+------------+----------------+
    | 18    | 262144      | 0x00040000 | 0xFFFBFFFF     |
    +-------+-------------+------------+----------------+
    | 19    | 524288      | 0x00080000 | 0xFFF7FFFF     |
    +-------+-------------+------------+----------------+
    | 20    | 1048576     | 0x00100000 | 0xFFEFFFFF     |
    +-------+-------------+------------+----------------+
    | 21    | 2097152     | 0x00200000 | 0xFFDFFFFF     |
    +-------+-------------+------------+----------------+
    | 22    | 4194304     | 0x00400000 | 0xFFBFFFFF     |
    +-------+-------------+------------+----------------+
    | 23    | 8388608     | 0x00800000 | 0xFF7FFFFF     |
    +-------+-------------+------------+----------------+
    | 24    | 16777216    | 0x01000000 | 0xFEFFFFFF     |
    +-------+-------------+------------+----------------+
    | 25    | 33554432    | 0x02000000 | 0xFDFFFFFF     |
    +-------+-------------+------------+----------------+
    | 26    | 67108864    | 0x04000000 | 0xFBFFFFFF     |
    +-------+-------------+------------+----------------+
    | 27    | 134217728   | 0x08000000 | 0xF7FFFFFF     |
    +-------+-------------+------------+----------------+
    | 28    | 268435456   | 0x10000000 | 0xEFFFFFFF     |
    +-------+-------------+------------+----------------+
    | 29    | 536870912   | 0x20000000 | 0xDFFFFFFF     |
    +-------+-------------+------------+----------------+
    | 30    | 1073741824  | 0x40000000 | 0xBFFFFFFF     |
    +-------+-------------+------------+----------------+
    | 31    | -2147483648 | 0x80000000 | 0x7FFFFFFF     |
    +-------+-------------+------------+----------------+
    | -1    | 0           | 0x00000000 | 0xFFFFFFFF     |
    +-------+-------------+------------+----------------+
    

    解决你的实际问题,你可能会这样做:

    DECLARE @yourNumber INT=15
    
    SELECT bm.BitNr
          ,CASE WHEN bm.Bitmap & @yourNumber>0 THEN 1 ELSE 0 END
    FROM @bitmaptable AS bm
    

    返回

    0   1
    1   1
    2   1
    3   1
    4   0
    5   0
    6   0
    7   0
    

    【讨论】:

      【解决方案3】:

      您可以尝试使用 CTE:

      declare @i int = 13
      
      ;with cte as(
          select 0 [n], @i % 2 [bits], @i / 2 [int]
          union all
          select [n] + 1, [int] % 2, [int] / 2 from cte
          where [int] / 2 > 0
      ), cte2 as (
          select [n] [relevance], [bits] from cte
          union all
          select MAX([n]) + 1, 1 from cte
      )
      
      select * from cte2
      --if you'd like to re-create number
      --select sum(POWER(2, relevance) * bits) from cte2
      

      这将导致 talbe 包含位。相关度根据n列,最大的n对应最相关(最左)位。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-31
        • 2016-03-20
        • 2018-01-02
        • 1970-01-01
        • 2018-09-24
        • 1970-01-01
        相关资源
        最近更新 更多